Пример #1
0
        /// <summary>
        /// Inherit values from parent node.
        /// </summary>
        internal static void InheritValues(PdfDictionary page, InheritedValues values)
        {
            // HACK: I'M ABSOLUTELY NOT SURE WHETHER THIS CODE COVERS ALL CASES.
            if (values.Resources != null)
            {
                PdfDictionary resources;
                PdfItem res = page.Elements[InheritablePageKeys.Resources];
                if (res is PdfReference)
                {
                    resources = (PdfDictionary)((PdfReference)res).Value.Clone();
                    resources.Document = page.Owner;
                }
                else
                    resources = (PdfDictionary)res;

                if (resources == null)
                {
                    resources = values.Resources.Clone();
                    resources.Document = page.Owner;
                    page.Elements.Add(InheritablePageKeys.Resources, resources);
                }
                else
                {
                    foreach (PdfName name in values.Resources.Elements.KeyNames)
                    {
                        if (!resources.Elements.ContainsKey(name.Value))
                        {
                            PdfItem item = values.Resources.Elements[name];
                            if (item is PdfObject)
                                item = item.Clone();
                            resources.Elements.Add(name.ToString(), item);
                        }
                    }
                }
            }

            if (values.MediaBox != null && page.Elements[InheritablePageKeys.MediaBox] == null)
                page.Elements[InheritablePageKeys.MediaBox] = values.MediaBox;

            if (values.CropBox != null && page.Elements[InheritablePageKeys.CropBox] == null)
                page.Elements[InheritablePageKeys.CropBox] = values.CropBox;

            if (values.Rotate != null && page.Elements[InheritablePageKeys.Rotate] == null)
                page.Elements[InheritablePageKeys.Rotate] = values.Rotate;
        }
Пример #2
0
        /// <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;
            }
        }
Пример #3
0
        internal override void WriteObject(PdfWriter writer)
        {
            // HACK: temporarily flip media box if Landscape
            PdfRectangle mediaBox = MediaBox;
            // TODO: Take /Rotate into account
            if (_orientation == PageOrientation.Landscape)
                MediaBox = new PdfRectangle(mediaBox.X1, mediaBox.Y1, mediaBox.Y2, mediaBox.X2);

            #if true
            // Add transparency group to prevent rendering problems of Adobe viewer.
            // Update (PDFsharp 1.50 beta 3): Add transparency group only of ColorMode is defined.
            // Rgb is the default for the ColorMode, but if user sets it to Undefined then
            // we respect this and skip the transparency group.
            TransparencyUsed = true; // TODO: check XObjects
            if (TransparencyUsed && !Elements.ContainsKey(Keys.Group) &&
                _document.Options.ColorMode != PdfColorMode.Undefined)
            {
                PdfDictionary group = new PdfDictionary();
                _elements["/Group"] = group;
                if (_document.Options.ColorMode != PdfColorMode.Cmyk)
                    group.Elements.SetName("/CS", "/DeviceRGB");
                else
                    group.Elements.SetName("/CS", "/DeviceCMYK");
                group.Elements.SetName("/S", "/Transparency");
                //False is default: group.Elements["/I"] = new PdfBoolean(false);
                //False is default: group.Elements["/K"] = new PdfBoolean(false);
            }
            #endif

            #if DEBUG_
            PdfItem item = Elements["/MediaBox"];
            if (item != null)
                item.GetType();
            #endif
            base.WriteObject(writer);

            if (_orientation == PageOrientation.Landscape)
                MediaBox = mediaBox;
        }
Пример #4
0
        /// <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);
        }
Пример #5
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.");
                }
            }
        }
        /// <summary>
        /// Initializes this instance from an exisiting PDF document.
        /// </summary>
        void Initialize()
        {
            string title;

            if (Elements.TryGetString(Keys.Title, out title))
            {
                Title = title;
            }

            PdfReference parentRef = Elements.GetReference(Keys.Parent);

            if (parentRef != null)
            {
                PdfOutline parent = parentRef.Value as PdfOutline;
                if (parent != null)
                {
                    Parent = parent;
                }
            }

            Count = Elements.GetInteger(Keys.Count);

            PdfArray colors = Elements.GetArray(Keys.C);

            if (colors != null && colors.Elements.Count == 3)
            {
                double r = colors.Elements.GetReal(0);
                double g = colors.Elements.GetReal(1);
                double b = colors.Elements.GetReal(2);
                TextColor = XColor.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
            }

            // Style directly works on dictionary element.

            PdfItem dest = Elements.GetValue(Keys.Dest);
            PdfItem a    = Elements.GetValue(Keys.A);

            Debug.Assert(dest == null || a == null, "Either destination or goto action.");

            if (dest != null)
            {
                if (dest is PdfArray destArray)
                {
                    SplitDestinationPage(destArray);
                }
                else
                {
                    Debug.Assert(false, "See what to do when this happened.");
                }
            }
            else if (a != null)
            {
                // The dictionary should be a GoTo action.
                PdfDictionary action = a as PdfDictionary;
                if (action != null && action.Elements.GetName(PdfAction.Keys.S) == "/GoTo")
                {
                    dest = action.Elements[PdfGoToAction.Keys.D];
                    if (dest is PdfArray destArray)
                    {
                        // Replace Action with /Dest entry.
                        Elements.Remove(Keys.A);
                        Elements.Add(Keys.Dest, destArray);
                        SplitDestinationPage(destArray);
                    }
                    else if (dest is PdfReference detRef)
                    {
                        // Replace Action with /Dest entry.
                        Elements.Remove(Keys.A);
                        Elements.Add(Keys.Dest, detRef.Value);
                        SplitDestinationPage((PdfArray)detRef.Value);
                    }
                    else
                    {
                        throw new Exception("Destination Array expected.");
                    }
                }
                else
                {
                    Debug.Assert(false, "See what to do when this happened.");
                }
            }
            else
            {
                // Neither destination page nor GoTo action.
            }

            InitializeChildren();
        }