/// <summary>Flushes the object to the document.</summary> /// <param name="canBeInObjStm">indicates whether object can be placed into object stream.</param> public void Flush(bool canBeInObjStm) { if (IsFlushed() || GetIndirectReference() == null || GetIndirectReference().IsFree()) { // TODO DEVSIX-744: here we should take into account and log the case when object is MustBeIndirect, but has no indirect reference // Logger logger = LoggerFactory.getLogger(PdfObject.class); // if (isFlushed()) { // logger.warn("Meaningless call, the object has already flushed"); // } else if (isIndirect()){ // logger.warn("Meaningless call, the object will be transformed into indirect on closing, but at the moment it doesn't have an indirect reference and therefore couldn't be flushed. " + // "To flush it now call makeIndirect(PdfDocument) method before calling flush() method."); // } else { // logger.warn("Meaningless call, the object is direct object. It will be flushed along with the indirect object that contains it."); // } return; } try { PdfDocument document = GetIndirectReference().GetDocument(); if (document != null) { if (document.IsAppendMode() && !IsModified()) { ILog logger = LogManager.GetLogger(typeof(PdfObject)); logger.Info(iText.IO.LogMessageConstant.PDF_OBJECT_FLUSHING_NOT_PERFORMED); return; } document.CheckIsoConformance(this, IsoKey.PDF_OBJECT); document.FlushObject(this, canBeInObjStm && GetObjectType() != STREAM && GetObjectType() != INDIRECT_REFERENCE && GetIndirectReference().GetGenNumber() == 0); } } catch (System.IO.IOException e) { throw new PdfException(PdfException.CannotFlushObject, e, this); } }
/// <summary>Flushes the object to the document.</summary> /// <param name="canBeInObjStm">indicates whether object can be placed into object stream.</param> /// <exception cref="iText.Kernel.PdfException"/> public void Flush(bool canBeInObjStm) { if (IsFlushed() || GetIndirectReference() == null) { // Logger logger = LoggerFactory.getLogger(PdfObject.class); // if (isFlushed()) { // logger.warn("Meaningless call, the object has already flushed"); // } else { // logger.warn("Meaningless call, the object is direct object."); // } return; } try { PdfDocument document = GetIndirectReference().GetDocument(); if (document != null) { document.CheckIsoConformance(this, IsoKey.PDF_OBJECT); document.FlushObject(this, canBeInObjStm && GetObjectType() != STREAM && GetObjectType() != INDIRECT_REFERENCE && GetIndirectReference().GetGenNumber() == 0); } } catch (System.IO.IOException e) { throw new PdfException(PdfException.CannotFlushObject, e, this); } }
public override void Flush() { PdfDictionary pageDict = GetPdfObject().GetAsDictionary(PdfName.Pg); if (pageDict == null || pageDict.GetIndirectReference() != null && pageDict.GetIndirectReference().IsFree( )) { GetPdfObject().Remove(PdfName.Pg); } PdfDocument doc = GetDocument(); if (doc != null) { doc.CheckIsoConformance(GetPdfObject(), IsoKey.TAG_STRUCTURE_ELEMENT); } base.Flush(); }
/// <summary>Writes cross reference table and trailer to PDF.</summary> /// <param name="document"> /// is the current /// <see cref="PdfDocument">document</see> /// </param> /// <param name="fileId">field id</param> /// <param name="crypto">pdf encryption</param> protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject crypto) { PdfWriter writer = document.GetWriter(); if (!document.properties.appendMode) { for (int i = count; i > 0; --i) { PdfIndirectReference lastRef = xref[i]; if (lastRef == null || lastRef.IsFree()) { RemoveFreeRefFromList(i); --count; } else { break; } } } PdfStream xrefStream = null; if (writer.IsFullCompression()) { xrefStream = new PdfStream(); xrefStream.MakeIndirect(document); } IList <int> sections = CreateSections(document, false); bool noModifiedObjects = (sections.Count == 0) || (xrefStream != null && sections.Count == 2 && sections[0 ] == count && sections[1] == 1); if (document.properties.appendMode && noModifiedObjects) { // No modifications in document xref = null; return; } document.CheckIsoConformance(this, IsoKey.XREF_TABLE); long startxref = writer.GetCurrentPos(); long xRefStmPos = -1; if (xrefStream != null) { xrefStream.Put(PdfName.Type, PdfName.XRef); xrefStream.Put(PdfName.ID, fileId); if (crypto != null) { xrefStream.Put(PdfName.Encrypt, crypto); } xrefStream.Put(PdfName.Size, new PdfNumber(this.Size())); int offsetSize = GetOffsetSize(Math.Max(startxref, Size())); xrefStream.Put(PdfName.W, new PdfArray(JavaUtil.ArraysAsList((PdfObject) new PdfNumber(1), new PdfNumber(offsetSize ), new PdfNumber(2)))); xrefStream.Put(PdfName.Info, document.GetDocumentInfo().GetPdfObject()); xrefStream.Put(PdfName.Root, document.GetCatalog().GetPdfObject()); PdfArray index = new PdfArray(); foreach (int?section in sections) { index.Add(new PdfNumber((int)section)); } if (document.properties.appendMode && !document.reader.hybridXref) { // "not meaningful in hybrid-reference files" PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref()); xrefStream.Put(PdfName.Prev, lastXref); } xrefStream.Put(PdfName.Index, index); xrefStream.GetIndirectReference().SetOffset(startxref); iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref(); for (int k = 0; k < sections.Count; k += 2) { int first = (int)sections[k]; int len = (int)sections[k + 1]; for (int i = first; i < first + len; i++) { PdfIndirectReference reference = xrefTable.Get(i); if (reference.IsFree()) { xrefStream.GetOutputStream().Write(0); xrefStream.GetOutputStream().Write(reference.GetOffset(), offsetSize); xrefStream.GetOutputStream().Write(reference.GetGenNumber(), 2); } else { if (reference.GetObjStreamNumber() == 0) { xrefStream.GetOutputStream().Write(1); xrefStream.GetOutputStream().Write(reference.GetOffset(), offsetSize); xrefStream.GetOutputStream().Write(reference.GetGenNumber(), 2); } else { xrefStream.GetOutputStream().Write(2); xrefStream.GetOutputStream().Write(reference.GetObjStreamNumber(), offsetSize); xrefStream.GetOutputStream().Write(reference.GetIndex(), 2); } } } } xrefStream.Flush(); xRefStmPos = startxref; } // For documents with hybrid cross-reference table, i.e. containing xref streams as well as regular xref sections, // we write additional regular xref section at the end of the document because the /Prev reference from // xref stream to a regular xref section doesn't seem to be valid bool needsRegularXref = !writer.IsFullCompression() || (document.properties.appendMode && document.reader. hybridXref); if (needsRegularXref) { startxref = writer.GetCurrentPos(); writer.WriteString("xref\n"); iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref(); if (xRefStmPos != -1) { // Get rid of all objects from object stream. This is done for hybrid documents sections = CreateSections(document, true); } for (int k = 0; k < sections.Count; k += 2) { int first = (int)sections[k]; int len = (int)sections[k + 1]; writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n'); for (int i = first; i < first + len; i++) { PdfIndirectReference reference = xrefTable.Get(i); StringBuilder off = new StringBuilder("0000000000").Append(reference.GetOffset()); StringBuilder gen = new StringBuilder("00000").Append(reference.GetGenNumber()); writer.WriteString(off.JSubstring(off.Length - 10, off.Length)).WriteSpace().WriteString(gen.JSubstring(gen .Length - 5, gen.Length)).WriteSpace(); if (reference.IsFree()) { writer.WriteBytes(freeXRefEntry); } else { writer.WriteBytes(inUseXRefEntry); } } } PdfDictionary trailer = document.GetTrailer(); // Remove all unused keys in case stamp mode in case original file has full compression, but destination file has not. trailer.Remove(PdfName.W); trailer.Remove(PdfName.Index); trailer.Remove(PdfName.Type); trailer.Remove(PdfName.Length); trailer.Put(PdfName.Size, new PdfNumber(this.Size())); trailer.Put(PdfName.ID, fileId); if (xRefStmPos != -1) { trailer.Put(PdfName.XRefStm, new PdfNumber(xRefStmPos)); } if (crypto != null) { trailer.Put(PdfName.Encrypt, crypto); } writer.WriteString("trailer\n"); if (document.properties.appendMode) { PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref()); trailer.Put(PdfName.Prev, lastXref); } writer.Write(document.GetTrailer()); writer.Write('\n'); } WriteKeyInfo(document); writer.WriteString("startxref\n").WriteLong(startxref).WriteString("\n%%EOF\n"); xref = null; freeReferencesLinkedList.Clear(); }