private void RemovePageTagFromParent(IPdfStructElem pageTag, IPdfStructElem parent) { if (parent is PdfStructElem) { PdfStructElem structParent = (PdfStructElem)parent; if (!structParent.IsFlushed()) { structParent.RemoveKid(pageTag); PdfDictionary parentObject = structParent.GetPdfObject(); if (!connectedStructToModel.ContainsKey(parentObject) && parent.GetKids().Count == 0 && parentObject != rootTagElement .GetPdfObject()) { RemovePageTagFromParent(structParent, parent.GetParent()); parentObject.GetIndirectReference().SetFree(); } } else { if (pageTag is PdfMcr) { throw new PdfException(PdfException.CannotRemoveTagBecauseItsParentIsFlushed); } } } }
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); } } } }
/// <summary>Defines index of the current tag in the parent's kids list.</summary> /// <returns> /// returns index of the current tag in the parent's kids list, or -1 /// if either current tag is a root tag, parent is flushed or it wasn't possible to define index. /// </returns> public virtual int GetIndexInParentKidsList() { if (GetCurrentStructElem().GetPdfObject() == tagStructureContext.GetRootTag().GetPdfObject()) { return(-1); } PdfStructElem parent = (PdfStructElem)GetCurrentStructElem().GetParent(); if (parent.IsFlushed()) { return(-1); } PdfObject k = parent.GetK(); if (k == GetCurrentStructElem().GetPdfObject()) { return(0); } if (k.IsArray()) { PdfArray kidsArr = (PdfArray)k; return(kidsArr.IndexOf(GetCurrentStructElem().GetPdfObject())); } return(-1); }
/// <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 any tag if document's tag structure was partially 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() { IPdfStructElem parentElem = GetCurrentStructElem().GetParent(); if (parentElem is PdfStructTreeRoot) { throw new PdfException(PdfException.CannotRemoveDocumentRootTag); } IList <IPdfStructElem> kids = GetCurrentStructElem().GetKids(); PdfStructElem parent = (PdfStructElem)parentElem; if (parent.IsFlushed()) { throw new PdfException(PdfException.CannotRemoveTagBecauseItsParentIsFlushed); } int removedKidIndex = parent.RemoveKid(GetCurrentStructElem()); GetCurrentStructElem().GetPdfObject().GetIndirectReference().SetFree(); foreach (IPdfStructElem kid in kids) { if (kid is PdfStructElem) { parent.AddKid(removedKidIndex++, (PdfStructElem)kid); } else { PdfMcr mcr = PrepareMcrForMovingToNewParent((PdfMcr)kid, parent); parent.AddKid(removedKidIndex++, mcr); } } SetCurrentStructElem(parent); return(this); }
internal virtual PdfStructElem GetCurrentStructElem() { if (currentStructElem.IsFlushed()) { throw new PdfException(PdfException.TagTreePointerIsInInvalidStateItPointsAtFlushedElementUseMoveToRoot); } if (currentStructElem.GetPdfObject().GetIndirectReference().IsFree()) { // is removed throw new PdfException(PdfException.TagTreePointerIsInInvalidStateItPointsAtRemovedElementUseMoveToRoot); } return(currentStructElem); }
/// <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); }
// it is StructTreeRoot // should never happen as we always should have only one root tag and we don't remove it private void FlushParentIfBelongsToPage(PdfStructElem parent, PdfPage currentPage) { if (parent.IsFlushed() || connectedStructToModel.ContainsKey(parent.GetPdfObject()) || parent.GetPdfObject () == rootTagElement.GetPdfObject()) { return; } IList <IPdfStructElem> kids = parent.GetKids(); bool allKidsBelongToPage = true; foreach (IPdfStructElem kid in kids) { if (kid is PdfMcr) { PdfDictionary kidPage = ((PdfMcr)kid).GetPageObject(); if (!kidPage.IsFlushed() && !kidPage.Equals(currentPage.GetPdfObject())) { allKidsBelongToPage = 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 // PdfStructElem. And therefore if we get into this if clause it means that some StructElem wasn't flushed. allKidsBelongToPage = false; break; } } } if (allKidsBelongToPage) { IPdfStructElem parentsParent = parent.GetParent(); parent.Flush(); if (parentsParent is PdfStructElem) { FlushParentIfBelongsToPage((PdfStructElem)parentsParent, currentPage); } } return; }
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); } } }
/// <summary> /// Moves this /// <see cref="TagTreePointer"/> /// instance to the parent of the current tag. /// </summary> /// <returns> /// this /// <see cref="TagTreePointer"/> /// instance. /// </returns> public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer MoveToParent() { if (GetCurrentStructElem().GetPdfObject() == tagStructureContext.GetRootTag().GetPdfObject()) { throw new PdfException(PdfException.CannotMoveToParentCurrentElementIsRoot); } PdfStructElem parent = (PdfStructElem)GetCurrentStructElem().GetParent(); if (parent.IsFlushed()) { ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagutils.TagTreePointer)); logger.Warn(iText.IO.LogMessageConstant.ATTEMPT_TO_MOVE_TO_FLUSHED_PARENT); MoveToRoot(); } else { SetCurrentStructElem((PdfStructElem)parent); } return(this); }