Esempio n. 1
0
 private void Write(PdfDictionary pdfDictionary)
 {
     WriteBytes(openDict);
     foreach (KeyValuePair <PdfName, PdfObject> entry in pdfDictionary.EntrySet())
     {
         bool isAlreadyWriteSpace = false;
         Write(entry.Key);
         PdfObject value = entry.Value;
         if (value == null)
         {
             ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfOutputStream));
             logger.Warn(String.Format(LogMessageConstant.INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE, entry.Key));
             value = PdfNull.PDF_NULL;
         }
         if ((value.GetObjectType() == PdfObject.NUMBER || value.GetObjectType() == PdfObject.LITERAL || value.GetObjectType
                  () == PdfObject.BOOLEAN || value.GetObjectType() == PdfObject.NULL || value.GetObjectType() == PdfObject
              .INDIRECT_REFERENCE || value.CheckState(PdfObject.MUST_BE_INDIRECT)))
         {
             isAlreadyWriteSpace = true;
             WriteSpace();
         }
         PdfIndirectReference indirectReference;
         if ((indirectReference = value.GetIndirectReference()) != null)
         {
             if (!isAlreadyWriteSpace)
             {
                 WriteSpace();
             }
             Write(indirectReference);
         }
         else
         {
             Write(value);
         }
     }
     WriteBytes(closeDict);
 }
Esempio n. 2
0
 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 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);
            }
        }
Esempio n. 4
0
        // For internal usage only
        /// <summary>Write a PdfObject to the outputstream.</summary>
        /// <param name="pdfObject">PdfObject to write</param>
        /// <returns>this PdfOutPutStream</returns>
        public virtual iText.Kernel.Pdf.PdfOutputStream Write(PdfObject pdfObject)
        {
            if (pdfObject.CheckState(PdfObject.MUST_BE_INDIRECT) && document != null)
            {
                pdfObject.MakeIndirect(document);
                pdfObject = pdfObject.GetIndirectReference();
            }
            if (pdfObject.CheckState(PdfObject.READ_ONLY))
            {
                throw new PdfException(PdfException.CannotWriteObjectAfterItWasReleased);
            }
            switch (pdfObject.GetObjectType())
            {
            case PdfObject.ARRAY: {
                Write((PdfArray)pdfObject);
                break;
            }

            case PdfObject.DICTIONARY: {
                Write((PdfDictionary)pdfObject);
                break;
            }

            case PdfObject.INDIRECT_REFERENCE: {
                Write((PdfIndirectReference)pdfObject);
                break;
            }

            case PdfObject.NAME: {
                Write((PdfName)pdfObject);
                break;
            }

            case PdfObject.NULL:
            case PdfObject.BOOLEAN: {
                Write((PdfPrimitiveObject)pdfObject);
                break;
            }

            case PdfObject.LITERAL: {
                Write((PdfLiteral)pdfObject);
                break;
            }

            case PdfObject.STRING: {
                Write((PdfString)pdfObject);
                break;
            }

            case PdfObject.NUMBER: {
                Write((PdfNumber)pdfObject);
                break;
            }

            case PdfObject.STREAM: {
                Write((PdfStream)pdfObject);
                break;
            }
            }
            return(this);
        }
Esempio n. 5
0
        private void LoadPage(int pageNum)
        {
            PdfIndirectReference targetPage = pageRefs[pageNum];

            if (targetPage != null)
            {
                return;
            }
            //if we go here, we have to split PdfPages that contains pageNum
            int      parentIndex = FindPageParent(pageNum);
            PdfPages parent      = parents[parentIndex];
            PdfArray kids        = parent.GetKids();

            if (kids == null)
            {
                throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
            }
            int kidsCount = parent.GetCount();
            // we should handle separated pages, it means every PdfArray kids must contain either PdfPage or PdfPages,
            // mix of PdfPage and PdfPages not allowed.
            bool findPdfPages = false;

            // NOTE optimization? when we already found needed index
            for (int i = 0; i < kids.Size(); i++)
            {
                PdfDictionary page = kids.GetAsDictionary(i);
                // null values not allowed in pages tree.
                if (page == null)
                {
                    throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                }
                PdfObject pageKids = page.Get(PdfName.Kids);
                if (pageKids != null)
                {
                    if (pageKids.IsArray())
                    {
                        findPdfPages = true;
                    }
                    else
                    {
                        // kids must be of type array
                        throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                    }
                }
                if (document.GetReader().IsMemorySavingMode() && !findPdfPages && parent.GetFrom() + i != pageNum)
                {
                    page.Release();
                }
            }
            if (findPdfPages)
            {
                // handle mix of PdfPage and PdfPages.
                // handle count property!
                IList <PdfPages> newParents   = new List <PdfPages>(kids.Size());
                PdfPages         lastPdfPages = null;
                for (int i = 0; i < kids.Size() && kidsCount > 0; i++)
                {
                    /*
                     * We don't release pdfPagesObject in the end of each loop because we enter this for-cycle only when parent has PdfPages kids.
                     * If all of the kids are PdfPages, then there's nothing to release, because we don't release PdfPages at this point.
                     * If there are kids that are instances of PdfPage, then there's no sense in releasing them:
                     * in this case ParentTreeStructure is being rebuilt by inserting an intermediate PdfPages between the parent and a PdfPage,
                     * thus modifying the page object by resetting its parent, thus making it impossible to release the object.
                     */
                    PdfDictionary pdfPagesObject = kids.GetAsDictionary(i);
                    if (pdfPagesObject.GetAsArray(PdfName.Kids) == null)
                    {
                        // pdfPagesObject is PdfPage
                        // possible if only first kid is PdfPage
                        if (lastPdfPages == null)
                        {
                            lastPdfPages = new PdfPages(parent.GetFrom(), document, parent);
                            kids.Set(i, lastPdfPages.GetPdfObject());
                            newParents.Add(lastPdfPages);
                        }
                        else
                        {
                            // Only remove from kids if we did not replace the entry with new PdfPages
                            kids.Remove(i);
                            i--;
                        }
                        // decrement count first so that page is not counted twice when moved to lastPdfPages
                        parent.DecrementCount();
                        lastPdfPages.AddPage(pdfPagesObject);
                        kidsCount--;
                    }
                    else
                    {
                        // pdfPagesObject is PdfPages
                        int from = lastPdfPages == null?parent.GetFrom() : lastPdfPages.GetFrom() + lastPdfPages.GetCount();

                        lastPdfPages = new PdfPages(from, kidsCount, pdfPagesObject, parent);
                        newParents.Add(lastPdfPages);
                        kidsCount -= lastPdfPages.GetCount();
                    }
                }
                parents.JRemoveAt(parentIndex);
                for (int i = newParents.Count - 1; i >= 0; i--)
                {
                    parents.Add(parentIndex, newParents[i]);
                }
                // recursive call, to load needed pageRef.
                // NOTE optimization? add to loadPage startParentIndex.
                LoadPage(pageNum);
            }
            else
            {
                int from = parent.GetFrom();
                // Possible exception in case kids.getSize() < parent.getCount().
                // In any case parent.getCount() has higher priority.
                // NOTE optimization? when we already found needed index
                for (int i = 0; i < parent.GetCount(); i++)
                {
                    PdfObject kid = kids.Get(i, false);
                    if (kid is PdfIndirectReference)
                    {
                        pageRefs[from + i] = (PdfIndirectReference)kid;
                    }
                    else
                    {
                        pageRefs[from + i] = kid.GetIndirectReference();
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>Add an entry to the name tree</summary>
        /// <param name="key">key of the entry</param>
        /// <param name="value">object to add</param>
        public virtual void AddEntry(String key, PdfObject value)
        {
            PdfObject existingVal = items.Get(key);

            if (existingVal != null)
            {
                if (value.GetIndirectReference() != null && value.GetIndirectReference().Equals(existingVal.GetIndirectReference
                                                                                                    ()))
                {
                    return;
                }
                else
                {
                    ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfNameTree));
                    logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.NAME_ALREADY_EXISTS_IN_THE_NAME_TREE, key
                                                         ));
                }
            }
            modified = true;
            items.Put(key, value);
        }
Esempio n. 7
0
 protected internal virtual int GetCopyObjectKey(PdfObject obj)
 {
     return(CalculateIndRefKey(obj.GetIndirectReference()));
 }