private static void GetUsedNonFlushedOCGsFromXObject(PdfDictionary toXObject, PdfDictionary fromXObject, ICollection <PdfIndirectReference> fromUsedOcgs, PdfDictionary toOcProperties) { if (toXObject != null && !toXObject.IsFlushed()) { if (toXObject.IsStream() && !toXObject.IsFlushed()) { PdfStream toStream = (PdfStream)toXObject; PdfStream fromStream = (PdfStream)fromXObject; iText.Kernel.Pdf.OcgPropertiesCopier.GetUsedNonFlushedOCGsFromOcDict(toStream.GetAsDictionary(PdfName.OC), fromStream.GetAsDictionary(PdfName.OC), fromUsedOcgs, toOcProperties); iText.Kernel.Pdf.OcgPropertiesCopier.GetUsedNonFlushedOCGsFromResources(toStream.GetAsDictionary(PdfName.Resources ), fromStream.GetAsDictionary(PdfName.Resources), fromUsedOcgs, toOcProperties); } else { foreach (PdfName name in toXObject.KeySet()) { PdfObject toCurrObj = toXObject.Get(name); PdfObject fromCurrObj = fromXObject.Get(name); if (toCurrObj.IsStream() && !toCurrObj.IsFlushed()) { PdfStream toStream = (PdfStream)toCurrObj; PdfStream fromStream = (PdfStream)fromCurrObj; iText.Kernel.Pdf.OcgPropertiesCopier.GetUsedNonFlushedOCGsFromXObject(toStream, fromStream, fromUsedOcgs, toOcProperties); } } } } }
private void CheckAndResolveCircularReferences(PdfObject pdfObject) { // Consider the situation when an XObject references the resources of the first page. // We add this XObject to the first page, there is no need to resolve any circular references // and then we flush this object and try to add it to the second page. // Now there are circular references and we cannot resolve them because the object is flushed // and we cannot get resources. // On the other hand, this situation may occur any time when object is already flushed and we // try to add it to resources and it seems difficult to overcome this without keeping /Resources key value. if (pdfObject is PdfDictionary && !pdfObject.IsFlushed()) { PdfDictionary pdfXObject = (PdfDictionary)pdfObject; PdfObject pdfXObjectResources = pdfXObject.Get(PdfName.Resources); if (pdfXObjectResources != null && pdfXObjectResources.GetIndirectReference() != null) { if (pdfXObjectResources.GetIndirectReference().Equals(GetPdfObject().GetIndirectReference())) { PdfObject cloneResources = GetPdfObject().Clone(); cloneResources.MakeIndirect(GetPdfObject().GetIndirectReference().GetDocument()); pdfXObject.Put(PdfName.Resources, cloneResources.GetIndirectReference()); } } } }
private static void GetUsedNonFlushedOCGsFromOcDict(PdfObject toObj, PdfObject fromObj, ICollection<PdfIndirectReference > fromUsedOcgs, PdfDictionary toOcProperties) { if (toObj != null && toObj.IsDictionary() && !toObj.IsFlushed()) { PdfDictionary toCurrDict = (PdfDictionary)toObj; PdfDictionary fromCurrDict = (PdfDictionary)fromObj; PdfName typeName = toCurrDict.GetAsName(PdfName.Type); if (PdfName.OCG.Equals(typeName) && !iText.Kernel.Pdf.OcgPropertiesCopier.OcgAlreadyInOCGs(toCurrDict.GetIndirectReference (), toOcProperties)) { fromUsedOcgs.Add(fromCurrDict.GetIndirectReference()); } else { if (PdfName.OCMD.Equals(typeName)) { PdfArray toOcgs = null; PdfArray fromOcgs = null; if (toCurrDict.GetAsDictionary(PdfName.OCGs) != null) { toOcgs = new PdfArray(); toOcgs.Add(toCurrDict.GetAsDictionary(PdfName.OCGs)); fromOcgs = new PdfArray(); fromOcgs.Add(fromCurrDict.GetAsDictionary(PdfName.OCGs)); } else { if (toCurrDict.GetAsArray(PdfName.OCGs) != null) { toOcgs = toCurrDict.GetAsArray(PdfName.OCGs); fromOcgs = fromCurrDict.GetAsArray(PdfName.OCGs); } } if (toOcgs != null && !toOcgs.IsFlushed()) { for (int i = 0; i < toOcgs.Size(); i++) { iText.Kernel.Pdf.OcgPropertiesCopier.GetUsedNonFlushedOCGsFromOcDict(toOcgs.Get(i), fromOcgs.Get(i), fromUsedOcgs , toOcProperties); } } } } } }
private void FlushObjectRecursively(PdfObject obj, PageFlushingHelper.DeepFlushingContext context) { if (obj == null) { return; } bool avoidReleaseForIndirectObjInstance = false; if (obj.IsIndirectReference()) { PdfIndirectReference indRef = (PdfIndirectReference)obj; if (indRef.refersTo == null || indRef.CheckState(PdfObject.FLUSHED)) { return; } obj = indRef.GetRefersTo(); } else { if (obj.IsFlushed()) { return; } else { if (release && obj.IsIndirect()) { // We should avoid the case when object is going to be released but is stored in containing object // not as indirect reference. This can happen when containing object is somehow modified. // Generally containing objects should not contain released read-only object instance. System.Diagnostics.Debug.Assert(obj.IsReleaseForbidden() || obj.GetIndirectReference() == null); avoidReleaseForIndirectObjInstance = true; } } } if (pdfDoc.IsDocumentFont(obj.GetIndirectReference()) || layersRefs.Contains(obj.GetIndirectReference())) { return; } if (obj.IsDictionary() || obj.IsStream()) { if (!currNestedObjParents.Add(obj)) { return; } FlushDictRecursively((PdfDictionary)obj, context); currNestedObjParents.Remove(obj); } else { if (obj.IsArray()) { if (!currNestedObjParents.Add(obj)) { return; } PdfArray array = (PdfArray)obj; for (int i = 0; i < array.Size(); ++i) { FlushObjectRecursively(array.Get(i, false), context); } currNestedObjParents.Remove(obj); } } if (!avoidReleaseForIndirectObjInstance) { FlushOrRelease(obj); } }