public virtual int GetNextMcidForPage(PdfPage page)
 {
     ParentTreeHandler.PageMcrsContainer pageMcrs = GetPageMarkedContentReferences(page);
     if (pageMcrs == null || pageMcrs.GetPageContentStreamsMcrs().Count == 0)
     {
         return(0);
     }
     else
     {
         return((int)Enumerable.Last(pageMcrs.GetPageContentStreamsMcrs()).Key + 1);
     }
 }
 /// <summary>Creates and flushes parent tree entry for the page.</summary>
 /// <remarks>
 /// Creates and flushes parent tree entry for the page.
 /// Effectively this means that new content mustn't be added to the page.
 /// </remarks>
 /// <param name="page">
 ///
 /// <see cref="iText.Kernel.Pdf.PdfPage"/>
 /// for which to create parent tree entry. Typically this page is flushed after this
 /// call.
 /// </param>
 public virtual void CreateParentTreeEntryForPage(PdfPage page)
 {
     ParentTreeHandler.PageMcrsContainer mcrs = GetPageMarkedContentReferences(page);
     if (mcrs == null)
     {
         return;
     }
     pageToPageMcrs.JRemove(page.GetPdfObject().GetIndirectReference());
     if (UpdateStructParentTreeEntries(page, mcrs))
     {
         structTreeRoot.SetModified();
     }
 }
        private bool UpdateStructParentTreeEntries(PdfPage page, ParentTreeHandler.PageMcrsContainer mcrs)
        {
            bool res = false;

            foreach (KeyValuePair <int, PdfMcr> entry in mcrs.GetObjRefs())
            {
                PdfMcr        mcr       = entry.Value;
                PdfDictionary parentObj = ((PdfStructElem)mcr.GetParent()).GetPdfObject();
                if (!parentObj.IsIndirect())
                {
                    continue;
                }
                int structParent = entry.Key;
                parentTree.AddEntry(structParent, parentObj);
                res = true;
            }
            int pageStructParentIndex;

            foreach (KeyValuePair <PdfIndirectReference, SortedDictionary <int, PdfMcr> > entry in mcrs.GetPageResourceXObjects
                         ())
            {
                PdfIndirectReference xObjectRef = entry.Key;
                if (xObjectToStructParentsInd.ContainsKey(xObjectRef))
                {
                    pageStructParentIndex = (int)xObjectToStructParentsInd.JRemove(xObjectRef);
                    if (UpdateStructParentTreeForContentStreamEntries(entry.Value, pageStructParentIndex))
                    {
                        res = true;
                    }
                }
            }
            if (page.IsFlushed())
            {
                PdfIndirectReference pageRef = page.GetPdfObject().GetIndirectReference();
                if (!pageToStructParentsInd.ContainsKey(pageRef))
                {
                    return(res);
                }
                pageStructParentIndex = (int)pageToStructParentsInd.JRemove(pageRef);
            }
            else
            {
                pageStructParentIndex = GetOrCreatePageStructParentIndex(page);
            }
            if (UpdateStructParentTreeForContentStreamEntries(mcrs.GetPageContentStreamsMcrs(), pageStructParentIndex)
                )
            {
                res = true;
            }
            return(res);
        }
 public virtual PdfObjRef FindObjRefByStructParentIndex(PdfDictionary pageDict, int structParentIndex)
 {
     ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(pageDict.GetIndirectReference());
     return(pageMcrs != null ? (PdfObjRef)pageMcrs.GetObjRefs().Get(structParentIndex) : null);
 }
 // Mind that this method searches among items contained in page's content stream  only
 public virtual PdfMcr FindMcrByMcid(PdfDictionary pageDict, int mcid)
 {
     ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(pageDict.GetIndirectReference());
     return(pageMcrs != null?pageMcrs.GetPageContentStreamsMcrs().Get(mcid) : null);
 }
        public virtual void UnregisterMcr(PdfMcr mcrToUnregister)
        {
            PdfDictionary pageDict = mcrToUnregister.GetPageObject();

            if (pageDict == null)
            {
                // invalid mcr, ignore
                return;
            }
            if (pageDict.IsFlushed())
            {
                throw new PdfException(PdfException.CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed);
            }
            ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(pageDict.GetIndirectReference());
            if (pageMcrs != null)
            {
                PdfObject stm;
                if ((stm = GetStm(mcrToUnregister)) != null)
                {
                    PdfIndirectReference xObjectReference = stm is PdfIndirectReference ? (PdfIndirectReference)stm : stm.GetIndirectReference
                                                                ();
                    pageMcrs.GetPageResourceXObjects().Get(xObjectReference).JRemove(mcrToUnregister.GetMcid());
                    if (pageMcrs.GetPageResourceXObjects().Get(xObjectReference).IsEmpty())
                    {
                        pageMcrs.GetPageResourceXObjects().JRemove(xObjectReference);
                        xObjectToStructParentsInd.JRemove(xObjectReference);
                    }
                    structTreeRoot.SetModified();
                }
                else
                {
                    if (mcrToUnregister is PdfObjRef)
                    {
                        PdfDictionary obj = ((PdfDictionary)mcrToUnregister.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                        if (obj != null && !obj.IsFlushed())
                        {
                            PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                            if (n != null)
                            {
                                pageMcrs.GetObjRefs().JRemove(n.IntValue());
                                structTreeRoot.SetModified();
                                return;
                            }
                        }
                        foreach (KeyValuePair <int, PdfMcr> entry in pageMcrs.GetObjRefs())
                        {
                            if (entry.Value.GetPdfObject() == mcrToUnregister.GetPdfObject())
                            {
                                pageMcrs.GetObjRefs().JRemove(entry.Key);
                                structTreeRoot.SetModified();
                                break;
                            }
                        }
                    }
                    else
                    {
                        pageMcrs.GetPageContentStreamsMcrs().JRemove(mcrToUnregister.GetMcid());
                        structTreeRoot.SetModified();
                    }
                }
            }
        }
        private void RegisterMcr(PdfMcr mcr, bool registeringOnInit)
        {
            PdfIndirectReference mcrPageIndRef = mcr.GetPageIndirectReference();

            if (mcrPageIndRef == null || (!(mcr is PdfObjRef) && mcr.GetMcid() < 0))
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
                logger.Error(iText.IO.LogMessageConstant.ENCOUNTERED_INVALID_MCR);
                return;
            }
            ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(mcrPageIndRef);
            if (pageMcrs == null)
            {
                pageMcrs = new ParentTreeHandler.PageMcrsContainer();
                pageToPageMcrs.Put(mcrPageIndRef, pageMcrs);
            }
            PdfObject stm;

            if ((stm = GetStm(mcr)) != null)
            {
                PdfIndirectReference stmIndRef;
                PdfStream            xObjectStream;
                if (stm is PdfIndirectReference)
                {
                    stmIndRef     = (PdfIndirectReference)stm;
                    xObjectStream = (PdfStream)stmIndRef.GetRefersTo();
                }
                else
                {
                    if (stm.GetIndirectReference() == null)
                    {
                        stm.MakeIndirect(structTreeRoot.GetDocument());
                    }
                    stmIndRef     = stm.GetIndirectReference();
                    xObjectStream = (PdfStream)stm;
                }
                int?structParent = xObjectStream.GetAsInt(PdfName.StructParents);
                if (structParent != null)
                {
                    xObjectToStructParentsInd.Put(stmIndRef, structParent);
                }
                else
                {
                    // TODO DEVSIX-3351 an error is thrown here because right now no /StructParents will be created.
                    ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
                    logger.Error(iText.IO.LogMessageConstant.XOBJECT_HAS_NO_STRUCT_PARENTS);
                }
                pageMcrs.PutXObjectMcr(stmIndRef, mcr);
                if (registeringOnInit)
                {
                    xObjectStream.Release();
                }
            }
            else
            {
                if (mcr is PdfObjRef)
                {
                    PdfDictionary obj = ((PdfDictionary)mcr.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                    if (obj == null || obj.IsFlushed())
                    {
                        throw new PdfException(PdfException.WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject
                                               );
                    }
                    PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                    if (n != null)
                    {
                        pageMcrs.PutObjectReferenceMcr(n.IntValue(), mcr);
                    }
                    else
                    {
                        throw new PdfException(PdfException.StructParentIndexNotFoundInTaggedObject);
                    }
                }
                else
                {
                    pageMcrs.PutPageContentStreamMcr(mcr.GetMcid(), mcr);
                }
            }
            if (!registeringOnInit)
            {
                structTreeRoot.SetModified();
            }
        }
 /// <summary>Gets an unmodifiable collection of marked content references on page.</summary>
 /// <remarks>
 /// Gets an unmodifiable collection of marked content references on page.
 /// NOTE: Do not remove tags when iterating over returned collection, this could
 /// lead to the ConcurrentModificationException, because returned collection is backed by the internal list of the
 /// actual page tags.
 /// </remarks>
 /// <param name="page">
 ///
 /// <see cref="iText.Kernel.Pdf.PdfPage"/>
 /// to obtain unmodifiable collection of marked content references
 /// </param>
 /// <returns>the unmodifiable collection of marked content references on page, if no Mcrs defined returns null
 ///     </returns>
 public virtual ICollection <PdfMcr> GetPageMarkedContentReferences(PdfPage page)
 {
     ParentTreeHandler.PageMcrsContainer pageMcrs = GetParentTreeHandler().GetPageMarkedContentReferences(page);
     return(pageMcrs != null?JavaCollectionsUtil.UnmodifiableCollection(pageMcrs.GetAllMcrsAsCollection()) :
                null);
 }