예제 #1
0
 private void RemovePageTagFromParent(IStructureNode pageTag, IStructureNode parent)
 {
     if (parent is PdfStructElem)
     {
         PdfStructElem structParent = (PdfStructElem)parent;
         if (!structParent.IsFlushed())
         {
             structParent.RemoveKid(pageTag);
             PdfDictionary parentStructDict = structParent.GetPdfObject();
             if (waitingTagsManager.GetObjForStructDict(parentStructDict) == null && parent.GetKids().Count == 0 && !(structParent
                                                                                                                      .GetParent() is PdfStructTreeRoot))
             {
                 RemovePageTagFromParent(structParent, parent.GetParent());
                 PdfIndirectReference indRef = parentStructDict.GetIndirectReference();
                 if (indRef != null)
                 {
                     // TODO how about possible references to structure element from refs or structure destination for instance?
                     indRef.SetFree();
                 }
             }
         }
         else
         {
             if (pageTag is PdfMcr)
             {
                 throw new PdfException(PdfException.CannotRemoveTagBecauseItsParentIsFlushed);
             }
         }
     }
 }
        public override PdfObject GetDestinationPage(IDictionary <String, PdfObject> names)
        {
            PdfObject firstObj = ((PdfArray)GetPdfObject()).Get(0);

            if (firstObj.IsDictionary())
            {
                PdfStructElem structElem = new PdfStructElem((PdfDictionary)firstObj);
                while (true)
                {
                    IList <IStructureNode> kids     = structElem.GetKids();
                    IStructureNode         firstKid = kids.Count > 0 ? kids[0] : null;
                    if (firstKid is PdfMcr)
                    {
                        return(((PdfMcr)firstKid).GetPageObject());
                    }
                    else
                    {
                        if (firstKid is PdfStructElem)
                        {
                            structElem = (PdfStructElem)firstKid;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            return(null);
        }
예제 #3
0
        public virtual IStructureNode RemoveKid(int index, bool prepareForReAdding)
        {
            PdfObject k = GetK();

            if (k == null || !k.IsArray() && index != 0)
            {
                throw new IndexOutOfRangeException();
            }
            if (k.IsArray())
            {
                PdfArray kidsArray = (PdfArray)k;
                k = kidsArray.Get(index);
                kidsArray.Remove(index);
                if (kidsArray.IsEmpty())
                {
                    GetPdfObject().Remove(PdfName.K);
                }
            }
            else
            {
                GetPdfObject().Remove(PdfName.K);
            }
            SetModified();
            IStructureNode removedKid = ConvertPdfObjectToIPdfStructElem(k);
            PdfDocument    doc        = GetDocument();

            if (removedKid is PdfMcr && doc != null && !prepareForReAdding)
            {
                doc.GetStructTreeRoot().GetParentTreeHandler().UnregisterMcr((PdfMcr)removedKid);
            }
            return(removedKid);
        }
예제 #4
0
 private void FlushAllKids(IStructureNode elem)
 {
     foreach (IStructureNode kid in elem.GetKids())
     {
         if (kid is PdfStructElem && !((PdfStructElem)kid).IsFlushed())
         {
             FlushAllKids(kid);
             ((PdfStructElem)kid).Flush();
         }
     }
 }
예제 #5
0
 private void RemoveWaitingStateAndFlushIfParentFlushed(PdfStructElem structElem)
 {
     if (structElem != null)
     {
         waitingTagToAssociatedObj.JRemove(structElem.GetPdfObject());
         IStructureNode parent = structElem.GetParent();
         if (parent is PdfStructElem && ((PdfStructElem)parent).IsFlushed())
         {
             FlushStructElementAndItKids(structElem);
         }
     }
 }
예제 #6
0
        /// <returns>parent of the flushed tag</returns>
        internal virtual IStructureNode FlushTag(PdfStructElem tagStruct)
        {
            Object associatedObj = waitingTagToAssociatedObj.JRemove(tagStruct.GetPdfObject());

            if (associatedObj != null)
            {
                associatedObjToWaitingTag.JRemove(associatedObj);
            }
            IStructureNode parent = tagStruct.GetParent();

            FlushStructElementAndItKids(tagStruct);
            return(parent);
        }
예제 #7
0
        /// <summary>
        /// Moves kid of the current tag to the tag at which given
        /// <c>TagTreePointer</c>
        /// points.
        /// This method doesn't change neither this instance nor pointerToNewParent position.
        /// </summary>
        /// <param name="kidIndex">zero-based index of the current tag's kid to be relocated.</param>
        /// <param name="pointerToNewParent">
        /// the
        /// <c>TagTreePointer</c>
        /// which is positioned at the tag which will become kid's new parent.
        /// </param>
        /// <returns>
        /// this
        /// <see cref="TagTreePointer"/>
        /// instance.
        /// </returns>
        public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer RelocateKid(int kidIndex, iText.Kernel.Pdf.Tagutils.TagTreePointer
                                                                            pointerToNewParent)
        {
            if (GetDocument() != pointerToNewParent.GetDocument())
            {
                throw new PdfException(PdfException.TagCannotBeMovedToTheAnotherDocumentsTagStructure);
            }
            if (GetCurrentStructElem().IsFlushed())
            {
                throw new PdfException(PdfException.CannotRelocateTagWhichParentIsAlreadyFlushed);
            }
            if (IsPointingToSameTag(pointerToNewParent))
            {
                if (kidIndex == pointerToNewParent.nextNewKidIndex)
                {
                    return(this);
                }
                else
                {
                    if (kidIndex < pointerToNewParent.nextNewKidIndex)
                    {
                        pointerToNewParent.SetNextNewKidIndex(pointerToNewParent.nextNewKidIndex - 1);
                    }
                }
            }
            if (GetCurrentStructElem().GetKids()[kidIndex] == null)
            {
                throw new PdfException(PdfException.CannotRelocateTagWhichIsAlreadyFlushed);
            }
            IStructureNode removedKid = GetCurrentStructElem().RemoveKid(kidIndex, true);

            if (removedKid is PdfStructElem)
            {
                pointerToNewParent.AddNewKid((PdfStructElem)removedKid);
            }
            else
            {
                if (removedKid is PdfMcr)
                {
                    PdfMcr mcrKid = PrepareMcrForMovingToNewParent((PdfMcr)removedKid, pointerToNewParent.GetCurrentStructElem
                                                                       ());
                    pointerToNewParent.AddNewKid(mcrKid);
                }
            }
            return(this);
        }
예제 #8
0
 private static IList<PdfDictionary> RetrieveParents(PdfMcr mcr, bool all) {
     IList<PdfDictionary> parents = new List<PdfDictionary>();
     IStructureNode firstParent = mcr.GetParent();
     PdfDictionary previous = null;
     PdfDictionary current = firstParent is PdfStructElem ? ((PdfStructElem)firstParent).GetPdfObject() : null;
     while (current != null && !PdfName.StructTreeRoot.Equals(current.GetAsName(PdfName.Type))) {
         if (all) {
             parents.Add(current);
         }
         previous = current;
         current = previous.IsFlushed() ? null : previous.GetAsDictionary(PdfName.P);
     }
     if (!all) {
         parents.Add(previous);
     }
     return parents;
 }
예제 #9
0
        /// <summary>Removes the current tag.</summary>
        /// <remarks>
        /// Removes the current tag. If it has kids, they will become kids of the current tag parent.
        /// This method call moves this
        /// <c>TagTreePointer</c>
        /// to the current tag parent.
        /// <br /><br />
        /// You cannot remove root tag, and also you cannot remove the tag if it's parent is already flushed;
        /// in this two cases an exception will be thrown.
        /// </remarks>
        /// <returns>
        /// this
        /// <see cref="TagStructureContext"/>
        /// instance.
        /// </returns>
        public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer RemoveTag()
        {
            PdfStructElem  currentStructElem = GetCurrentStructElem();
            IStructureNode parentElem        = currentStructElem.GetParent();

            if (parentElem is PdfStructTreeRoot)
            {
                throw new PdfException(PdfException.CannotRemoveDocumentRootTag);
            }
            IList <IStructureNode> kids   = currentStructElem.GetKids();
            PdfStructElem          parent = (PdfStructElem)parentElem;

            if (parent.IsFlushed())
            {
                throw new PdfException(PdfException.CannotRemoveTagBecauseItsParentIsFlushed);
            }
            // remove waiting tag state if tag is removed
            Object objForStructDict = tagStructureContext.GetWaitingTagsManager().GetObjForStructDict(currentStructElem
                                                                                                      .GetPdfObject());

            tagStructureContext.GetWaitingTagsManager().RemoveWaitingState(objForStructDict);
            int removedKidIndex         = parent.RemoveKid(currentStructElem);
            PdfIndirectReference indRef = currentStructElem.GetPdfObject().GetIndirectReference();

            if (indRef != null)
            {
                // TODO how about possible references to structure element from refs or structure destination for instance?
                indRef.SetFree();
            }
            foreach (IStructureNode kid in kids)
            {
                if (kid is PdfStructElem)
                {
                    parent.AddKid(removedKidIndex++, (PdfStructElem)kid);
                }
                else
                {
                    PdfMcr mcr = PrepareMcrForMovingToNewParent((PdfMcr)kid, parent);
                    parent.AddKid(removedKidIndex++, mcr);
                }
            }
            currentStructElem.GetPdfObject().Clear();
            SetCurrentStructElem(parent);
            return(this);
        }
예제 #10
0
        /// <summary>Flushes current tag and all it's descendants.</summary>
        /// <remarks>
        /// Flushes current tag and all it's descendants.
        /// This method call moves this
        /// <c>TagTreePointer</c>
        /// to the current tag parent.
        /// <p>
        /// If some of the descendant tags of the current tag have waiting state (see
        /// <see cref="WaitingTagsManager"/>
        /// ),
        /// then these tags are considered as not yet finished ones, and they won't be flushed immediately,
        /// but they will be flushed, when waiting state is removed.
        /// </p>
        /// </remarks>
        /// <returns>
        /// this
        /// <see cref="TagTreePointer"/>
        /// instance.
        /// </returns>
        public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer FlushTag()
        {
            if (GetCurrentStructElem().GetPdfObject() == tagStructureContext.GetRootTag().GetPdfObject())
            {
                throw new PdfException(PdfException.CannotFlushDocumentRootTagBeforeDocumentIsClosed);
            }
            IStructureNode parent = tagStructureContext.GetWaitingTagsManager().FlushTag(GetCurrentStructElem());

            if (parent != null)
            {
                // parent is not flushed
                SetCurrentStructElem((PdfStructElem)parent);
            }
            else
            {
                SetCurrentStructElem(tagStructureContext.GetRootTag());
            }
            return(this);
        }
예제 #11
0
        internal virtual void FlushParentIfBelongsToPage(PdfStructElem parent, PdfPage currentPage)
        {
            if (parent.IsFlushed() || waitingTagsManager.GetObjForStructDict(parent.GetPdfObject()) != null || parent.
                GetParent() is PdfStructTreeRoot)
            {
                return;
            }
            IList <IStructureNode> kids = parent.GetKids();
            bool readyToBeFlushed       = true;

            foreach (IStructureNode kid in kids)
            {
                if (kid is PdfMcr)
                {
                    PdfDictionary kidPage = ((PdfMcr)kid).GetPageObject();
                    if (!kidPage.IsFlushed() && (currentPage == null || !kidPage.Equals(currentPage.GetPdfObject())))
                    {
                        readyToBeFlushed = false;
                        break;
                    }
                }
                else
                {
                    if (kid is PdfStructElem)
                    {
                        // If kid is structElem and was already flushed then in kids list there will be null for it instead of
                        // PdfStructElement. And therefore if we get into this if-clause it means that some StructElem wasn't flushed.
                        readyToBeFlushed = false;
                        break;
                    }
                }
            }
            if (readyToBeFlushed)
            {
                IStructureNode parentsParent = parent.GetParent();
                parent.Flush();
                if (parentsParent is PdfStructElem)
                {
                    FlushParentIfBelongsToPage((PdfStructElem)parentsParent, currentPage);
                }
            }
        }
예제 #12
0
 protected internal virtual void InspectKid(IStructureNode kid)
 {
     try {
         if (kid is PdfStructElem)
         {
             PdfStructElem structElemKid = (PdfStructElem)kid;
             PdfName       s             = structElemKid.GetRole();
             String        tagN          = s.GetValue();
             String        tag           = FixTagName(tagN);
             @out.Write("<");
             @out.Write(tag);
             InspectAttributes(structElemKid);
             @out.Write(">" + Environment.NewLine);
             PdfString alt = (structElemKid).GetAlt();
             if (alt != null)
             {
                 @out.Write("<alt><![CDATA[");
                 @out.Write(iText.IO.Util.StringUtil.ReplaceAll(alt.GetValue(), "[\\000]*", ""));
                 @out.Write("]]></alt>" + Environment.NewLine);
             }
             InspectKids(structElemKid.GetKids());
             @out.Write("</");
             @out.Write(tag);
             @out.Write(">" + Environment.NewLine);
         }
         else
         {
             if (kid is PdfMcr)
             {
                 ParseTag((PdfMcr)kid);
             }
             else
             {
                 @out.Write(" <flushedKid/> ");
             }
         }
     }
     catch (System.IO.IOException e) {
         throw new iText.IO.IOException(iText.IO.IOException.UnknownIOException, e);
     }
 }
예제 #13
0
        /// <summary>
        /// Moves this
        /// <c>TagTreePointer</c>
        /// instance to the kid of the current tag.
        /// </summary>
        /// <param name="kidIndex">zero-based index of the current tag kid to which pointer will be moved.</param>
        /// <returns>
        /// this
        /// <see cref="TagTreePointer"/>
        /// instance.
        /// </returns>
        public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer MoveToKid(int kidIndex)
        {
            IStructureNode kid = GetCurrentStructElem().GetKids()[kidIndex];

            if (kid is PdfStructElem)
            {
                SetCurrentStructElem((PdfStructElem)kid);
            }
            else
            {
                if (kid is PdfMcr)
                {
                    throw new PdfException(PdfException.CannotMoveToMarkedContentReference);
                }
                else
                {
                    throw new PdfException(PdfException.CannotMoveToFlushedKid);
                }
            }
            return(this);
        }
예제 #14
0
 public virtual int RemoveKid(IStructureNode kid)
 {
     if (kid is PdfMcr)
     {
         PdfMcr      mcr = (PdfMcr)kid;
         PdfDocument doc = GetDocument();
         if (doc != null)
         {
             doc.GetStructTreeRoot().GetParentTreeHandler().UnregisterMcr(mcr);
         }
         return(RemoveKidObject(mcr.GetPdfObject()));
     }
     else
     {
         if (kid is iText.Kernel.Pdf.Tagging.PdfStructElem)
         {
             return(RemoveKidObject(((iText.Kernel.Pdf.Tagging.PdfStructElem)kid).GetPdfObject()));
         }
     }
     return(-1);
 }
예제 #15
0
        private IStructureNode ConvertPdfObjectToIPdfStructElem(PdfObject obj)
        {
            IStructureNode elem = null;

            switch (obj.GetObjectType())
            {
            case PdfObject.DICTIONARY: {
                PdfDictionary d = (PdfDictionary)obj;
                if (IsStructElem(d))
                {
                    elem = new iText.Kernel.Pdf.Tagging.PdfStructElem(d);
                }
                else
                {
                    if (PdfName.MCR.Equals(d.GetAsName(PdfName.Type)))
                    {
                        elem = new PdfMcrDictionary(d, this);
                    }
                    else
                    {
                        if (PdfName.OBJR.Equals(d.GetAsName(PdfName.Type)))
                        {
                            elem = new PdfObjRef(d, this);
                        }
                    }
                }
                break;
            }

            case PdfObject.NUMBER: {
                elem = new PdfMcrNumber((PdfNumber)obj, this);
                break;
            }

            default: {
                break;
            }
            }
            return(elem);
        }
예제 #16
0
        private static void Process(IStructureNode elem, StringBuilder builder)
        {
            if (elem == null)
            {
                return;
            }

            builder.Append("Role: " + elem.GetRole() + "\n");
            builder.Append("Class name: " + elem.GetType().FullName + "\n");
            if (elem is PdfStructElem)
            {
                ProcessStructElem((PdfStructElem)elem, builder);
            }

            if (elem.GetKids() != null)
            {
                foreach (IStructureNode structElem in elem.GetKids())
                {
                    Process(structElem, builder);
                }
            }
        }