/// <summary> /// Add all inheritable values from the specified page to the specified values structure. /// </summary> internal static void InheritValues(PdfDictionary page, ref InheritedValues values) { PdfItem item = page.Elements[InheritablePageKeys.Resources]; if (item != null) { PdfReference reference = item as PdfReference; if (reference != null) { values.Resources = (PdfDictionary)(reference.Value); } else { values.Resources = (PdfDictionary)item; } } item = page.Elements[InheritablePageKeys.MediaBox]; if (item != null) { values.MediaBox = new PdfRectangle(item); } item = page.Elements[InheritablePageKeys.CropBox]; if (item != null) { values.CropBox = new PdfRectangle(item); } item = page.Elements[InheritablePageKeys.Rotate]; if (item != null) { if (item is PdfReference) { item = ((PdfReference)item).Value; } values.Rotate = (PdfInteger)item; } }
/// <summary> /// Initializes a new instance of the PdfRectangle class with the specified PdfArray. /// </summary> internal PdfRectangle(PdfItem item) { if (item == null || item is PdfNull) { return; } if (item is PdfReference) { item = ((PdfReference)item).Value; } PdfArray array = item as PdfArray; if (array == null) { throw new InvalidOperationException(PSSR.UnexpectedTokenInPdfFile); } _x1 = array.Elements.GetReal(0); _y1 = array.Elements.GetReal(1); _x2 = array.Elements.GetReal(2); _y2 = array.Elements.GetReal(3); }
/// <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."); } } }