/// <summary> /// Inserts pages of the specified document into this document. /// </summary> /// <param name="index">The index in this document where to insert the page .</param> /// <param name="document">The document to be inserted.</param> /// <param name="startIndex">The index of the first page to be inserted.</param> /// <param name="pageCount">The number of pages to be inserted.</param> public void InsertRange(int index, PDFDocument document, int startIndex, int pageCount) { if (document == null) { throw new ArgumentNullException("document"); } if (index < 0 || index > Count) { throw new ArgumentOutOfRangeException("index", "Argument 'index' out of range."); } int importDocumentPageCount = document.PageCount; if (startIndex < 0 || startIndex + pageCount > importDocumentPageCount) { throw new ArgumentOutOfRangeException("startIndex", "Argument 'startIndex' out of range."); } if (pageCount > importDocumentPageCount) { throw new ArgumentOutOfRangeException("pageCount", "Argument 'pageCount' out of range."); } PDFPage[] insertPages = new PDFPage[pageCount]; PDFPage[] importPages = new PDFPage[pageCount]; // 1st create all new pages. for (int idx = 0, insertIndex = index, importIndex = startIndex; importIndex < startIndex + pageCount; idx++, insertIndex++, importIndex++) { PDFPage importPage = document.Pages[importIndex]; PDFPage page = ImportExternalPage(importPage); insertPages[idx] = page; importPages[idx] = importPage; Owner.IrefTable.Add(page); // Add page substitute to importedObjectTable. PDFImportedObjectTable importedObjectTable = Owner.ExternalDocumentTable.GetImportedObjectTable(importPage); importedObjectTable.Add(importPage.ObjectID, page.Reference); PagesArray.Elements.Insert(insertIndex, page.Reference); if (Owner.Settings.TrimMargins.AreSet) { page.TrimMargins = Owner.Settings.TrimMargins; } } Elements.SetInteger(Keys.Count, PagesArray.Elements.Count); // 2nd copy link annotations that are in the range of the imported pages. for (int idx = 0, importIndex = startIndex; importIndex < startIndex + pageCount; idx++, importIndex++) { PDFPage importPage = document.Pages[importIndex]; PDFPage page = insertPages[idx]; // Get annotations. PDFArray annots = importPage.Elements.GetArray(PDFPage.Keys.Annots); if (annots != null) { PDFAnnotations annotations = new PDFAnnotations(Owner); // Loop through annotations. int count = annots.Elements.Count; for (int idxAnnotation = 0; idxAnnotation < count; idxAnnotation++) { PDFDictionary annot = annots.Elements.GetDictionary(idxAnnotation); if (annot != null) { string subtype = annot.Elements.GetString(PDFAnnotation.Keys.Subtype); if (subtype == "/Link") { bool addAnnotation = false; PDFLinkAnnotation newAnnotation = new PDFLinkAnnotation(Owner); PDFName[] importAnnotationKeyNames = annot.Elements.KeyNames; foreach (PDFName pdfItem in importAnnotationKeyNames) { PDFItem impItem; switch (pdfItem.Value) { case "/BS": newAnnotation.Elements.Add("/BS", new PDFLiteral("<</W 0>>")); break; case "/F": // /F 4 impItem = annot.Elements.GetValue("/F"); Debug.Assert(impItem is PDFInteger); newAnnotation.Elements.Add("/F", impItem.Clone()); break; case "/Rect": // /Rect [68.6 681.08 145.71 702.53] impItem = annot.Elements.GetValue("/Rect"); Debug.Assert(impItem is PDFArray); newAnnotation.Elements.Add("/Rect", impItem.Clone()); break; case "/StructParent": // /StructParent 3 impItem = annot.Elements.GetValue("/StructParent"); Debug.Assert(impItem is PDFInteger); newAnnotation.Elements.Add("/StructParent", impItem.Clone()); break; case "/Subtype": // Already set. break; case "/Dest": // /Dest [30 0 R /XYZ 68 771 0] impItem = annot.Elements.GetValue("/Dest"); impItem = impItem.Clone(); // Is value an array with 5 elements where the first one is an iref? PDFArray destArray = impItem as PDFArray; if (destArray != null && destArray.Elements.Count == 5) { if (destArray.Elements[0] is PDFReference iref) { iref = RemapReference(insertPages, importPages, iref); if (iref != null) { destArray.Elements[0] = iref; newAnnotation.Elements.Add("/Dest", destArray); addAnnotation = true; } } } break; default: #if DEBUG_ Debug - Break.Break(true); #endif break; } } // Add newAnnotations only it points to an imported page. if (addAnnotation) { annotations.Add(newAnnotation); } } } } // At least one link annotation found? if (annotations.Count > 0) { //Owner._irefTable.Add(annotations); page.Elements.Add(PDFPage.Keys.Annots, annotations); } } } }
/// <summary> /// Inserts the specified PDFPage at the specified position to this document and maybe returns a new PDFPage object. /// The value returned is a new object if the inserted page comes from a foreign document. /// </summary> public PDFPage Insert(int index, PDFPage page) { if (page == null) { throw new ArgumentNullException("page"); } // Is the page already owned by this document? if (page.Owner == Owner) { // Case: Page is first removed and than inserted again, maybe at another position. int count = Count; // Check if page is not already part of the document. for (int idx = 0; idx < count; idx++) { if (ReferenceEquals(this[idx], page)) { throw new InvalidOperationException(PSSR.MultiplePageInsert); } } // TODO: check this case // Because the owner of the inserted page is this document we assume that the page was former part of it // and it is therefore well-defined. Owner.IrefTable.Add(page); Debug.Assert(page.Owner == Owner); // Insert page in array. PagesArray.Elements.Insert(index, page.Reference); // Update page count. Elements.SetInteger(Keys.Count, PagesArray.Elements.Count); return(page); } // All new page insertions come here. if (page.Owner == null) { // Case: New page was newly created and inserted now. page.Document = Owner; Owner.IrefTable.Add(page); Debug.Assert(page.Owner == Owner); PagesArray.Elements.Insert(index, page.Reference); Elements.SetInteger(Keys.Count, PagesArray.Elements.Count); } else { // Case: Page is from an external document -> import it. PDFPage importPage = page; page = ImportExternalPage(importPage); Owner.IrefTable.Add(page); // Add page substitute to importedObjectTable. PDFImportedObjectTable importedObjectTable = Owner.ExternalDocumentTable.GetImportedObjectTable(importPage); importedObjectTable.Add(importPage.ObjectID, page.Reference); PagesArray.Elements.Insert(index, page.Reference); Elements.SetInteger(Keys.Count, PagesArray.Elements.Count); PDFAnnotations.FixImportedAnnotation(page); } if (Owner.Settings.TrimMargins.AreSet) { page.TrimMargins = Owner.Settings.TrimMargins; } return(page); }