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); }
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); }
private void FlushAllKids(IStructureNode elem) { foreach (IStructureNode kid in elem.GetKids()) { if (kid is PdfStructElem && !((PdfStructElem)kid).IsFlushed()) { FlushAllKids(kid); ((PdfStructElem)kid).Flush(); } } }
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); } } }
/// <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); }
/// <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); }
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; }
/// <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); }
/// <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); }
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); } } }
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); } }
/// <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); }
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); }
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); }
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); } } }