Ejemplo n.º 1
0
        /// <summary>
        /// Helper function for ImportExternalPage.
        /// </summary>
        void CloneElement(PdfPage page, PdfPage importPage, string key, bool deepcopy)
        {
            Debug.Assert(page != null);
            Debug.Assert(page.Owner == _document);
            Debug.Assert(importPage.Owner != null);
            Debug.Assert(importPage.Owner != _document);

            PdfItem item = importPage.Elements[key];

            if (item != null)
            {
                PdfImportedObjectTable importedObjectTable = null;
                if (!deepcopy)
                {
                    importedObjectTable = Owner.FormTable.GetImportedObjectTable(importPage);
                }

                // The item can be indirect. If so, replace it by its value.
                if (item is PdfReference)
                {
                    item = ((PdfReference)item).Value;
                }
                if (item is PdfObject)
                {
                    PdfObject root = (PdfObject)item;
                    if (deepcopy)
                    {
                        Debug.Assert(root.Owner != null, "See 'else' case for details");
                        root = DeepCopyClosure(_document, root);
                    }
                    else
                    {
                        // The owner can be null if the item is not a reference.
                        if (root.Owner == null)
                        {
                            root.Document = importPage.Owner;
                        }
                        root = ImportClosure(importedObjectTable, page.Owner, root);
                    }

                    if (root.Reference == null)
                    {
                        page.Elements[key] = root;
                    }
                    else
                    {
                        page.Elements[key] = root.Reference;
                    }
                }
                else
                {
                    // Simple items are just cloned.
                    page.Elements[key] = item.Clone();
                }
            }
        }
Ejemplo n.º 2
0
        private PdfReference FixDocumentRef(PdfItem objItem, PdfImportedObjectTable importedObjectTable)
        {
            if (objItem == null)
            {
                return(null);
            }
            var obj = objItem as PdfObject;

            if (obj != null)
            {
                obj._document = _document;
            }
            var dict = obj as PdfDictionary;

            if (dict != null)
            {
                foreach (var key in dict.Elements.KeyNames)
                {
                    var r = FixDocumentRef(dict.Elements[key], importedObjectTable);
                    if (r != null)
                    {
                        dict.Elements.SetReference(key.Value, r.Value);
                    }
                }
            }
            var array = obj as PdfArray;

            if (array != null)
            {
                for (var i = 0; i < array.Elements.Count; i++)
                {
                    var r = FixDocumentRef(array.Elements[i], importedObjectTable);
                    if (r != null)
                    {
                        array.Elements[i] = r;
                    }
                }
            }
            var reference = objItem as PdfReference;

            if (reference != null && reference.Document != _document)
            {
                if (importedObjectTable.Contains(reference.ObjectID))
                {
                    return(importedObjectTable[reference.ObjectID]);
                }
                var value = ImportClosure(importedObjectTable, _document, reference.Value);
                Debug.Assert(value.Reference != null);
                return(value.Reference);
            }
            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Replace all indirect references to external objects by their cloned counterparts
        /// owned by the importer document.
        /// </summary>
        static void FixUpObject(PdfImportedObjectTable iot, PdfDocument owner, PdfObject value)
        {
            Debug.Assert(ReferenceEquals(iot.Owner, owner));

            PdfDictionary dict;
            PdfArray      array;

            if ((dict = value as PdfDictionary) != null)
            {
                // Case: The object is a dictionary.
                // Set document for cloned direct objects.
                if (dict.Owner == null)
                {
                    // If the dictionary has not yet an owner set the owner to the importing document.
                    dict.Document = owner;
                }
                else
                {
                    // If the dictionary already has an owner it must be the importing document.
                    Debug.Assert(dict.Owner == owner);
                }

                // Search for indirect references in all dictionary elements.
                PdfName[] names = dict.Elements.KeyNames;
                foreach (PdfName name in names)
                {
                    PdfItem item = dict.Elements[name];
                    Debug.Assert(item != null, "A dictionary element cannot be null.");

                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Case: The item is a reference.
                        // Does the iref already belongs to the new owner?
                        if (iref.Document == owner)
                        {
                            // Yes: fine. Happens when an already cloned object is reused.
                            continue;
                        }

                        //Debug.Assert(iref.Document == iot.Document);
                        // No: Replace with iref of cloned object.
                        PdfReference newXRef = iot[iref.ObjectID];  // TODO: Explain this line of code in all details.
                        Debug.Assert(newXRef != null);
                        Debug.Assert(newXRef.Document == owner);
                        dict.Elements[name] = newXRef;
                    }
                    else
                    {
                        // Case: The item is not a reference.
                        // If item is an object recursively fix its inner items.
                        PdfObject pdfObject = item as PdfObject;
                        if (pdfObject != null)
                        {
                            // Fix up inner objects, i.e. recursively walk down the object tree.
                            FixUpObject(iot, owner, pdfObject);
                        }
                        else
                        {
                            // The item is something else, e.g. a name.
                            // Nothing to do.

                            // ...but let's double check this case in DEBUG build.
                            DebugCheckNonObjects(item);
                        }
                    }
                }
            }
            else if ((array = value as PdfArray) != null)
            {
                // Case: The object is an array.
                // Set document for cloned direct objects.
                if (array.Owner == null)
                {
                    // If the array has not yet an owner set the owner to the importing document.
                    array.Document = owner;
                }
                else
                {
                    // If the array already has an owner it must be the importing document.
                    Debug.Assert(array.Owner == owner);
                }

                // Search for indirect references in all array elements.
                int count = array.Elements.Count;
                for (int idx = 0; idx < count; idx++)
                {
                    PdfItem item = array.Elements[idx];
                    Debug.Assert(item != null, "An array element cannot be null.");

                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Case: The item is a reference.
                        // Does the iref already belongs to the owner?
                        if (iref.Document == owner)
                        {
                            // Yes: fine. Happens when an already cloned object is reused.
                            continue;
                        }

                        // No: replace with iref of cloned object.
                        Debug.Assert(iref.Document == iot.ExternalDocument);
                        PdfReference newXRef = iot[iref.ObjectID];
                        Debug.Assert(newXRef != null);
                        Debug.Assert(newXRef.Document == owner);
                        array.Elements[idx] = newXRef;
                    }
                    else
                    {
                        // Case: The item is not a reference.
                        // If item is an object recursively fix its inner items.
                        PdfObject pdfObject = item as PdfObject;
                        if (pdfObject != null)
                        {
                            // Fix up inner objects, i.e. recursively walk down the object tree.
                            FixUpObject(iot, owner, pdfObject);
                        }
                        else
                        {
                            // The item is something else, e.g. a name.
                            // Nothing to do.

                            // ...but let's double check this case in DEBUG build.
                            DebugCheckNonObjects(item);
                        }
                    }
                }
            }
            else
            {
                // Case: The item is some other indirect object.
                // Indirect integers, booleans, etc. are allowed, but PDFsharp do not create them.
                // If such objects occur in imported PDF files from other producers, nothing more is to do.
                // The owner was already set, which is double checked by the assertions below.
                if (value is PdfNameObject || value is PdfStringObject || value is PdfBooleanObject || value is PdfIntegerObject || value is PdfNumberObject)
                {
                    Debug.Assert(value.IsIndirect);
                    Debug.Assert(value.Owner == owner);
                }
                else
                {
                    Debug.Assert(false, "Should not come here. Object is neither a dictionary nor an array.");
                }
            }
        }
Ejemplo n.º 4
0
        ///// <summary>
        ///// Imports an object and its transitive closure to the specified document.
        ///// </summary>
        /// <param name="importedObjectTable">The imported object table of the owner for the external document.</param>
        /// <param name="owner">The document that owns the cloned objects.</param>
        /// <param name="externalObject">The root object to be cloned.</param>
        /// <returns>The clone of the root object</returns>
        internal static PdfObject ImportClosure(PdfImportedObjectTable importedObjectTable, PdfDocument owner, PdfObject externalObject)
        {
            Debug.Assert(ReferenceEquals(importedObjectTable.Owner, owner), "importedObjectTable does not belong to the owner.");
            Debug.Assert(ReferenceEquals(importedObjectTable.ExternalDocument, externalObject.Owner),
                         "The ExternalDocument of the importedObjectTable does not belong to the owner of object to be imported.");

            // Get transitive closure of external object.
            PdfObject[] elements = externalObject.Owner.Internals.GetClosure(externalObject);
            int         count    = elements.Length;

#if DEBUG_
            for (int idx = 0; idx < count; idx++)
            {
                Debug.Assert(elements[idx].XRef != null);
                Debug.Assert(elements[idx].XRef.Document != null);
                Debug.Assert(elements[idx].Document != null);
                if (elements[idx].ObjectID.ObjectNumber == 12)
                {
                    GetType();
                }
            }
#endif
            // 1st loop. Already imported objects are reused and new ones are cloned.
            for (int idx = 0; idx < count; idx++)
            {
                PdfObject obj = elements[idx];
                Debug.Assert(!ReferenceEquals(obj.Owner, owner));

                if (importedObjectTable.Contains(obj.ObjectID))
                {
#if DEBUG_
                    if (obj.ObjectID.ObjectNumber == 5894)
                    {
                        obj.GetType();
                    }
#endif
                    // Case: External object was already imported.
                    PdfReference iref = importedObjectTable[obj.ObjectID];
                    Debug.Assert(iref != null);
                    Debug.Assert(iref.Value != null);
                    Debug.Assert(iref.Document == owner);
                    // Replace external object by the already cloned counterpart.
                    elements[idx] = iref.Value;
                }
                else
                {
                    // Case: External object was not yet imported earlier and must be cloned.
                    PdfObject clone = obj.Clone();
                    Debug.Assert(clone.Reference == null);
                    clone.Document = owner;
                    if (obj.Reference != null)
                    {
                        // Case: The cloned object was an indirect object.
                        // Add clone to new owner document.
                        owner._irefTable.Add(clone);
                        Debug.Assert(clone.Reference != null);
                        // Save an association from old object identifier to new iref.
                        importedObjectTable.Add(obj.ObjectID, clone.Reference);
                    }
                    else
                    {
                        // Case: The cloned object was a direct object.
                        // Only the root object can be a direct object.
                        Debug.Assert(idx == 0);
                    }
                    // Replace external object by its clone.
                    elements[idx] = clone;
                }
            }
#if DEBUG_
            for (int idx = 0; idx < count; idx++)
            {
                //Debug.Assert(elements[idx].Reference != null);
                //Debug.Assert(elements[idx].Reference.Document != null);
                Debug.Assert(elements[idx].IsIndirect == false);
                Debug.Assert(elements[idx].Owner != null);
                //if (elements[idx].ObjectID.ObjectNumber == 12)
                //    GetType();
            }
#endif
            // 2nd loop. Fix up indirect references that still refers to the external document.
            for (int idx = 0; idx < count; idx++)
            {
                PdfObject obj = elements[idx];
                Debug.Assert(owner != null);
                FixUpObject(importedObjectTable, importedObjectTable.Owner, obj);
            }

            // Return the imported root object.
            return(elements[0]);
        }
Ejemplo n.º 5
0
        ///// <summary>
        ///// Creates a deep copy of the specified value and its transitive closure and adds the
        ///// new objects to the specified owner document.
        ///// </summary>
        /// <param name="owner">The document that owns the cloned objects.</param>
        /// <param name="externalObject">The root object to be cloned.</param>
        /// <returns>The clone of the root object</returns>
        internal static PdfObject DeepCopyClosure(PdfDocument owner, PdfObject externalObject)
        {
            // Get transitive closure.
            PdfObject[] elements = externalObject.Owner.Internals.GetClosure(externalObject);
            int         count    = elements.Length;

#if DEBUG_
            for (int idx = 0; idx < count; idx++)
            {
                Debug.Assert(elements[idx].XRef != null);
                Debug.Assert(elements[idx].XRef.Document != null);
                Debug.Assert(elements[idx].Document != null);
                if (elements[idx].ObjectID.ObjectNumber == 12)
                {
                    GetType();
                }
            }
#endif
            // 1st loop. Replace all objects by their clones.
            PdfImportedObjectTable iot = new PdfImportedObjectTable(owner, externalObject.Owner);
            for (int idx = 0; idx < count; idx++)
            {
                PdfObject obj   = elements[idx];
                PdfObject clone = obj.Clone();
                Debug.Assert(clone.Reference == null);
                clone.Document = owner;
                if (obj.Reference != null)
                {
                    // Case: The cloned object was an indirect object.
                    // Add clone to new owner document.
                    owner._irefTable.Add(clone);
                    // The clone gets an iref by adding it to its new owner.
                    Debug.Assert(clone.Reference != null);
                    // Save an association from old object identifier to new iref.
                    iot.Add(obj.ObjectID, clone.Reference);
                }
                else
                {
                    // Case: The cloned object was an direct object.
                    // Only the root object can be a direct object.
                    Debug.Assert(idx == 0);
                }
                // Replace external object by its clone.
                elements[idx] = clone;
            }
#if DEBUG_
            for (int idx = 0; idx < count; idx++)
            {
                Debug.Assert(elements[idx]._iref != null);
                Debug.Assert(elements[idx]._iref.Document != null);
                Debug.Assert(resources[idx].Document != null);
                if (elements[idx].ObjectID.ObjectNumber == 12)
                {
                    GetType();
                }
            }
#endif

            // 2nd loop. Fix up all indirect references that still refers to the import document.
            for (int idx = 0; idx < count; idx++)
            {
                PdfObject obj = elements[idx];
                Debug.Assert(obj.Owner == owner);
                FixUpObject(iot, owner, obj);
            }

            // Return the clone of the former root object.
            return(elements[0]);
        }
Ejemplo n.º 6
0
        /// <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.FormTable.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)
                                        {
                                            PdfReference iref = destArray.Elements[0] as PdfReference;
                                            if (iref != null)
                                            {
                                                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);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <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.FormTable.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);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Replace all indirect references to external objects by their cloned counterparts
        /// owned by the importer document.
        /// </summary>
        internal static void FixUpObject(PdfImportedObjectTable iot, PdfDocument owner, PdfObject value)
        {
            Debug.Assert(ReferenceEquals(iot.Owner, owner));

            PdfDictionary dict;
            PdfArray      array;

            if ((dict = value as PdfDictionary) != null)
            {
                // Set document for cloned direct objects
                if (dict.Owner == null)
                {
                    dict.Document = owner;
                }
                else
                {
                    Debug.Assert(dict.Owner == owner);
                }

                // Search for indirect references in all keys
                PdfName[] names = dict.Elements.KeyNames;
                foreach (PdfName name in names)
                {
                    PdfItem item = dict.Elements[name];
                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Does the iref already belongs to the owner?
                        if (iref.Document == owner)
                        {
                            // Yes: fine. Happens when an already cloned object is reused.
                            continue;
                        }
                        else
                        {
                            //Debug.Assert(iref.Document == iot.Document);
                            // No: replace with iref of cloned object
                            PdfReference newXRef = iot[iref.ObjectID];
                            Debug.Assert(newXRef != null);
                            Debug.Assert(newXRef.Document == owner);
                            dict.Elements[name] = newXRef;
                        }
                    }
                    else if (item is PdfObject)
                    {
                        // Fix up inner objects
                        FixUpObject(iot, owner, (PdfObject)item);
                    }
                }
            }
            else if ((array = value as PdfArray) != null)
            {
                // Set document for cloned direct objects
                if (array.Owner == null)
                {
                    array.Document = owner;
                }
                else
                {
                    Debug.Assert(array.Owner == owner);
                }

                // Search for indirect references in all array elements
                int count = array.Elements.Count;
                for (int idx = 0; idx < count; idx++)
                {
                    PdfItem item = array.Elements[idx];
                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Does the iref already belongs to the owner?
                        if (iref.Document == owner)
                        {
                            // Yes: fine. Happens when an already cloned object is reused.
                            continue;
                        }
                        else
                        {
                            Debug.Assert(iref.Document == iot.ExternalDocument);
                            // No: replace with iref of cloned object
                            PdfReference newXRef = iot[iref.ObjectID];
                            Debug.Assert(newXRef != null);
                            Debug.Assert(newXRef.Document == owner);
                            array.Elements[idx] = newXRef;
                        }
                    }
                    else if (item is PdfObject)
                    {
                        // Fix up inner objects
                        FixUpObject(iot, owner, (PdfObject)item);
                    }
                }
            }
        }
Ejemplo n.º 9
0
 private void ImportAcroField(PdfPage page, PdfPage importPage, PdfAcroForm localForm, PdfImportedObjectTable importedObjectTable, PdfAcroField fieldObj, bool isChild)
 {
     if (fieldObj != null)
     {
         PdfDictionary importedObject;
         if (!importedObjectTable.Contains(fieldObj.ObjectID))
         {
             // Do not use PdfObject.DeepCopyClosure as that would also create new Pages when encountering the "/P" Entry  !
             importedObject = ImportClosure(importedObjectTable, _document, fieldObj) as PdfDictionary;
         }
         else
         {
             importedObject = importedObjectTable[fieldObj.ObjectID].Value as PdfDictionary;
         }
         Debug.Assert(importedObject != null, "Imported AcroField is null");
         if (importedObject != null)
         {
             var name = importedObject is PdfAcroField ? ((PdfAcroField)importedObject).FullyQualifiedName : "NoName";
             Debug.WriteLine(String.Format("Importing {0} '{1}' ({2})", importedObject.GetType().Name, name, importedObject.ObjectID));
             if (importedObject.Elements.ContainsKey("/P"))
             {
                 var fieldPage = importedObject.Elements.GetObject(PdfAnnotation.Keys.Page);
                 Debug.Assert(_document._irefTable.Contains(fieldPage.ObjectID), "Page of imported field should exist in current document");
             }
             if (!isChild && !IsInArray(localForm.Fields, importedObject))
             {
                 localForm.Fields.Elements.Add(importedObject);
             }
         }
     }
 }
Ejemplo n.º 10
0
 private void FixAcroFields(PdfAcroField.PdfAcroFieldCollection formFields, PdfImportedObjectTable importedObjectTable)
 {
     for (var i = 0; i < formFields.Elements.Count; i++)
     {
         var field = formFields[i];
         if (field.Owner != _document)
         {
             field._document = _document;
         }
         field.Reference.Document = _document;
         if (field.ObjectID.IsEmpty || !_document._irefTable.Contains(field.ObjectID))
         {
             _document._irefTable.Add(field);
         }
         //// fix the /P entry for Field-Annotations
         //var fieldPage = field.Elements.GetDictionary(PdfAcroField.Keys.Page);
         //if (fieldPage != null && fieldPage.Owner != _document)
         //{
         //    var importedPage = importedObjectTable.Contains(fieldPage.ObjectID) ? importedObjectTable[fieldPage.ObjectID] : null;
         //    if (importedPage != null)
         //    {
         //        field.Elements.SetReference(PdfAcroField.Keys.Page, importedPage.Value);
         //        Debug.WriteLine(String.Format("Fixed page of '{0}' ({1}) -> {2} = {3}", field.FullyQualifiedName, field.ObjectID, fieldPage.ObjectID, importedPage.ObjectID));
         //    }
         //    else
         //        Debug.WriteLine(String.Format("Can't fix page of '{0}' ({1}), imported page not found", field.FullyQualifiedName, field.ObjectID));
         //}
         // Annotations are "partly" imported, we need to fix the /P entry
         for (var a = 0; a < field.Annotations.Elements.Count; a++)
         {
             var widget = field.Annotations.Elements[a];
             if (widget != null)
             {
                 // the owner has to be fixed as well...
                 // Note: it was observed that some objects referenced by the widget were still owned by the imported document, but that seems to be fixed on saving...
                 if (widget.Owner != _document)
                 {
                     if (_document._irefTable.Contains(widget.ObjectID))
                     {
                         widget._document          = _document;
                         widget.Reference.Document = _document;
                         if (!_document._irefTable.Contains(widget.ObjectID))
                         {
                             _document._irefTable.Add(widget);
                         }
                     }
                     else
                     {
                         // this was never needed during debugging, we leave it here just in case...
                         var importedWidget = ImportClosure(importedObjectTable, _document, widget) as PdfDictionary;
                         if (importedWidget != null)
                         {
                             widget = new PdfWidgetAnnotation(importedWidget);
                         }
                     }
                     FixDocumentRef(widget, importedObjectTable);
                 }
                 var widgetPage = widget.Page;
                 if (widgetPage != null && widgetPage.Owner != _document)
                 {
                     var importedPage = importedObjectTable.Contains(widgetPage.ObjectID) ? importedObjectTable[widgetPage.ObjectID] : null;
                     if (importedPage != null)
                     {
                         widget.Elements.SetReference(PdfAnnotation.Keys.Page, importedPage.Value);
                         Debug.WriteLine(String.Format("Fixed page of Widget '{0}' ({1}) -> {2} = {3}", field.FullyQualifiedName, field.ObjectID, widgetPage.ObjectID, importedPage.ObjectID));
                         var ip = importedPage.Value as PdfPage;
                         // the widget is a PdfWidgetAnnotation, but the "real" object may be something else (e.g. a PdfGenericField), so we check the referenced object instead
                         if (ip != null && !ip.Annotations.Elements.Contains(widget.Reference))
                         {
                             ip.Annotations.Elements.Add(widget.Reference.Value);
                         }
                     }
                 }
                 else if (widgetPage is PdfPage)
                 {
                     // add widget to the pages' annotations if not already present
                     if (!((PdfPage)widgetPage).Annotations.Elements.Contains(widget.Reference))
                     {
                         ((PdfPage)widgetPage).Annotations.Elements.Add(widget);
                     }
                 }
             }
         }
         if (field.HasKids)
         {
             FixAcroFields(field.Fields, importedObjectTable);
         }
     }
 }
Ejemplo n.º 11
0
        /// <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);

                // @PDF/UA: Pages must not be moved.
                if (_document._uaManager != null)
                {
                    _document.Events.OnPageAdded(_document, new PageEventArgs {
                        Page = page, PageIndex = index, EventType = PageEventType.Moved
                    });
                }

                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);

                // @PDF/UA: Page was created.
                if (_document._uaManager != null)
                {
                    _document.Events.OnPageAdded(_document, new PageEventArgs {
                        Page = page, PageIndex = index, EventType = PageEventType.Created
                    });
                }
            }
            else
            {
#if true
                // original code
                // 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.FormTable.GetImportedObjectTable(importPage);
                importedObjectTable.Add(importPage.ObjectID, page.Reference);

                PagesArray.Elements.Insert(index, page.Reference);
                Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
                PdfAnnotations.FixImportedAnnotation(page);
#else
                var externalPage = page;
                // Case: Page is from an external document -> import it.
                page = ImportExternalPage(externalPage);

                Owner._irefTable.Add(page);
                // Add page substitute to importedObjectTable.
                PdfImportedObjectTable importedObjectTable = Owner.FormTable.GetImportedObjectTable(externalPage);
                importedObjectTable.Add(externalPage.ObjectID, page.Reference);

                PagesArray.Elements.Insert(index, page.Reference);
                Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);

                PagesArray.Elements.Insert(index, page.Reference);
                Elements.SetInteger(PdfPages.Keys.Count, PagesArray.Elements.Count);

                // Import AcroFields, after the external Page has been imported and we have a valid ObjectID for the imported Page
                ImportAcroFields(page, externalPage);
                PdfAnnotations.FixImportedAnnotation(page);
#endif

                // @PDF/UA: Page was imported.
                if (_document._uaManager != null)
                {
                    _document.Events.OnPageAdded(_document, new PageEventArgs {
                        Page = page, PageIndex = index, EventType = PageEventType.Imported
                    });
                }
            }
            if (Owner.Settings.TrimMargins.AreSet)
            {
                page.TrimMargins = Owner.Settings.TrimMargins;
            }

            return(page);
        }