コード例 #1
0
        /**
          <param name="file">Associated file.</param>
          <param name="dataObject">
        <para>Data object associated to the indirect object. It MUST be</para>
        <list type="bullet">
          <item><code>null</code>, if the indirect object is original or free.</item>
          <item>NOT <code>null</code>, if the indirect object is new and in-use.</item>
        </list>
          </param>
          <param name="xrefEntry">Cross-reference entry associated to the indirect object. If the
        indirect object is new, its offset field MUST be set to 0.</param>
        */
        internal PdfIndirectObject(
      File file,
      PdfDataObject dataObject,
      XRefEntry xrefEntry
      )
        {
            this.file = file;
              this.dataObject = Include(dataObject);
              this.xrefEntry = xrefEntry;

              this.original = (xrefEntry.Offset >= 0);
              this.reference = new PdfReference(this);
        }
コード例 #2
0
ファイル: Visitor.cs プロジェクト: n9/pdfclown
 public virtual PdfObject Visit(
     PdfReference obj,
     object data
     )
 {
     obj.IndirectObject.Accept(this, data);
       return obj;
 }
コード例 #3
0
ファイル: Optimizer.cs プロジェクト: n9/pdfclown
            public override PdfObject Visit(
                PdfReference obj,
                object data
                )
            {
                int objectNumber = obj.Reference.ObjectNumber;
                if(aliveObjectNumbers.Contains(objectNumber))
                  return obj;

                aliveObjectNumbers.Add(objectNumber);
                return base.Visit(obj, data);
            }
コード例 #4
0
ファイル: Cloner.cs プロジェクト: josuecorrea/DanfeSharp
   public override PdfObject Visit(
 PdfReference obj,
 object data
 )
   {
       return context == obj.File
       ? (PdfReference)obj.Clone() // Local clone.
       : Visit(obj.IndirectObject, data).Reference; // Alien clone.
   }
コード例 #5
0
ファイル: File.cs プロジェクト: josuecorrea/DanfeSharp
   /**
     <summary>Unregisters an internal object.</summary>
   */
   public void Unregister(
 PdfReference reference
 )
   {
       indirectObjects.RemoveAt(reference.ObjectNumber);
   }
コード例 #6
0
ファイル: NameTree.cs プロジェクト: systembugtj/bookasa
            private KeyValuePair <PdfString, TValue>?GetNext(
                )
            {
                /*
                 * NOTE: Algorithm:
                 * 1. [Vertical, down] We have to go downward the name tree till we reach
                 * a names collection (leaf node).
                 * 2. [Horizontal] Then we iterate across the names collection.
                 * 3. [Vertical, up] When leaf-nodes scan is complete, we go upward solving
                 * parent nodes, repeating step 1.
                 */
                while (true)
                {
                    if (names == null)
                    {
                        if (kids == null ||
                            kids.Count == levelIndex) // Kids subtree complete.
                        {
                            if (levels.Count == 0)
                            {
                                return(null);
                            }

                            // 3. Go upward one level.
                            // Restore current level!
                            object[] level = levels.Pop();
                            container  = (PdfIndirectObject)level[0];
                            kids       = (PdfArray)level[1];
                            levelIndex = ((int)level[2]) + 1; // Next node (partially scanned level).
                        }
                        else // Kids subtree incomplete.
                        {
                            // 1. Go downward one level.
                            // Save current level!
                            levels.Push(new object[] { container, kids, levelIndex });

                            // Move downward!
                            PdfReference kidReference = (PdfReference)kids[levelIndex];
                            container = kidReference.IndirectObject;
                            PdfDictionary   kid        = (PdfDictionary)kidReference.DataObject;
                            PdfDirectObject kidsObject = kid[PdfName.Kids];
                            if (kidsObject == null) // Leaf node.
                            {
                                PdfDirectObject namesObject = kid[PdfName.Names];
                                if (namesObject is PdfReference)
                                {
                                    container = ((PdfReference)namesObject).IndirectObject;
                                }
                                names = (PdfArray)File.Resolve(namesObject);
                                kids  = null;
                            }
                            else // Intermediate node.
                            {
                                if (kidsObject is PdfReference)
                                {
                                    container = ((PdfReference)kidsObject).IndirectObject;
                                }
                                kids = (PdfArray)File.Resolve(kidsObject);
                            }
                            levelIndex = 0; // First node (new level).
                        }
                    }
                    else
                    {
                        if (names.Count == levelIndex) // Names complete.
                        {
                            names = null;
                        }
                        else // Names incomplete.
                        {
                            // 2. Object found.
                            PdfString key   = (PdfString)names[levelIndex];
                            TValue    value = nameTree.Wrap(
                                names[levelIndex + 1],
                                container,
                                key
                                );
                            levelIndex += 2;

                            return(new KeyValuePair <PdfString, TValue>(key, value));
                        }
                    }
                }
            }
コード例 #7
0
        /**
         * <summary>Adds an entry under the given tree node.</summary>
         * <param name="key">New entry's key.</param>
         * <param name="value">New entry's value.</param>
         * <param name="overwrite">Whether the entry is allowed to replace an existing one having the same
         * key.</param>
         * <param name="nodeReference">Current node reference.</param>
         */
        private void Add(
            TKey key,
            TValue value,
            bool overwrite,
            PdfDictionary node
            )
        {
            Children children = Children.Get(node, pairsKey);

            if (children.IsLeaf()) // Leaf node.
            {
                int childrenSize = children.Items.Count;
                int low = 0, high = childrenSize - children.Info.ItemCount;
                while (true)
                {
                    if (low > high)
                    {
                        // Insert the entry!
                        children.Items.Insert(low, key);
                        children.Items.Insert(++low, value.BaseObject);
                        break;
                    }

                    int mid = (mid = ((low + high) / 2)) - (mid % 2);
                    if (mid >= childrenSize)
                    {
                        // Append the entry!
                        children.Items.Add(key);
                        children.Items.Add(value.BaseObject);
                        break;
                    }

                    int comparison = key.CompareTo(children.Items[mid]);
                    if (comparison < 0) // Before.
                    {
                        high = mid - 2;
                    }
                    else if (comparison > 0) // After.
                    {
                        low = mid + 2;
                    }
                    else // Matching entry.
                    {
                        if (!overwrite)
                        {
                            throw new ArgumentException("Key '" + key + "' already exists.", "key");
                        }

                        // Overwrite the entry!
                        children.Items[mid]   = key;
                        children.Items[++mid] = value.BaseObject;
                        break;
                    }
                }

                // Update the key limits!
                UpdateNodeLimits(children);
            }
            else // Intermediate node.
            {
                int low = 0, high = children.Items.Count - children.Info.ItemCount;
                while (true)
                {
                    bool          matched      = false;
                    int           mid          = (low + high) / 2;
                    PdfReference  kidReference = (PdfReference)children.Items[mid];
                    PdfDictionary kid          = (PdfDictionary)kidReference.DataObject;
                    PdfArray      limits       = (PdfArray)kid.Resolve(PdfName.Limits);
                    if (key.CompareTo(limits[0]) < 0) // Before the lower limit.
                    {
                        high = mid - 1;
                    }
                    else if (key.CompareTo(limits[1]) > 0) // After the upper limit.
                    {
                        low = mid + 1;
                    }
                    else // Limit range matched.
                    {
                        matched = true;
                    }

                    if (matched || // Limit range matched.
                        low > high) // No limit range match.
                    {
                        Children kidChildren = Children.Get(kid, pairsKey);
                        if (kidChildren.IsFull())
                        {
                            // Split the node!
                            SplitFullNode(
                                children.Items,
                                mid,
                                kidChildren.TypeName
                                );
                            // Is the key before the split node?
                            if (key.CompareTo(((PdfArray)kid.Resolve(PdfName.Limits))[0]) < 0)
                            {
                                kidReference = (PdfReference)children.Items[mid];
                                kid          = (PdfDictionary)kidReference.DataObject;
                            }
                        }

                        Add(key, value, overwrite, kid);
                        // Update the key limits!
                        UpdateNodeLimits(children);
                        break;
                    }
                }
            }
        }
コード例 #8
0
        public virtual bool Remove(
            TKey key
            )
        {
            PdfDictionary        node = BaseDataObject;
            Stack <PdfReference> nodeReferenceStack = new Stack <PdfReference>();

            while (true)
            {
                Children nodeChildren = Children.Get(node, pairsKey);
                if (nodeChildren.IsLeaf()) // Leaf node.
                {
                    int low = 0, high = nodeChildren.Items.Count - nodeChildren.Info.ItemCount;
                    while (true)
                    {
                        if (low > high) // No match.
                        {
                            return(false);
                        }

                        int mid        = (mid = ((low + high) / 2)) - (mid % 2);
                        int comparison = key.CompareTo(nodeChildren.Items[mid]);
                        if (comparison < 0) // Key before.
                        {
                            high = mid - 2;
                        }
                        else if (comparison > 0) // Key after.
                        {
                            low = mid + 2;
                        }
                        else // Key matched.
                        {
                            // We got it!
                            nodeChildren.Items.RemoveAt(mid + 1);            // Removes value.
                            nodeChildren.Items.RemoveAt(mid);                // Removes key.
                            if (mid == 0 || mid == nodeChildren.Items.Count) // Limits changed.
                            {
                                // Update key limits!
                                UpdateNodeLimits(nodeChildren);

                                // Updating key limits on ascendants...
                                PdfReference rootReference = (PdfReference)BaseObject;
                                PdfReference nodeReference;
                                while (nodeReferenceStack.Count > 0 && !(nodeReference = nodeReferenceStack.Pop()).Equals(rootReference))
                                {
                                    PdfArray parentChildren = (PdfArray)nodeReference.Parent;
                                    int      nodeIndex      = parentChildren.IndexOf(nodeReference);
                                    if (nodeIndex == 0 || nodeIndex == parentChildren.Count - 1)
                                    {
                                        PdfDictionary parent = (PdfDictionary)parentChildren.Parent;
                                        UpdateNodeLimits(parent, parentChildren, PdfName.Kids);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            return(true);
                        }
                    }
                }
                else // Intermediate node.
                {
                    int low = 0, high = nodeChildren.Items.Count - nodeChildren.Info.ItemCount;
                    while (true)
                    {
                        if (low > high) // Outside the limit range.
                        {
                            return(false);
                        }

                        int           mid          = (low + high) / 2;
                        PdfReference  kidReference = (PdfReference)nodeChildren.Items[mid];
                        PdfDictionary kid          = (PdfDictionary)kidReference.DataObject;
                        PdfArray      limits       = (PdfArray)kid.Resolve(PdfName.Limits);
                        if (key.CompareTo(limits[0]) < 0) // Before the lower limit.
                        {
                            high = mid - 1;
                        }
                        else if (key.CompareTo(limits[1]) > 0) // After the upper limit.
                        {
                            low = mid + 1;
                        }
                        else // Limit range matched.
                        {
                            Children kidChildren = Children.Get(kid, pairsKey);
                            if (kidChildren.IsUndersized())
                            {
                                /*
                                 * NOTE: Rebalancing is required as minimum node size invariant is violated.
                                 */
                                PdfDictionary leftSibling         = null;
                                Children      leftSiblingChildren = null;
                                if (mid > 0)
                                {
                                    leftSibling         = (PdfDictionary)nodeChildren.Items.Resolve(mid - 1);
                                    leftSiblingChildren = Children.Get(leftSibling, pairsKey);
                                }
                                PdfDictionary rightSibling         = null;
                                Children      rightSiblingChildren = null;
                                if (mid < nodeChildren.Items.Count - 1)
                                {
                                    rightSibling         = (PdfDictionary)nodeChildren.Items.Resolve(mid + 1);
                                    rightSiblingChildren = Children.Get(rightSibling, pairsKey);
                                }

                                if (leftSiblingChildren != null && !leftSiblingChildren.IsUndersized())
                                {
                                    // Move the last child subtree of the left sibling to be the first child subtree of the kid!
                                    for (int index = 0, endIndex = leftSiblingChildren.Info.ItemCount; index < endIndex; index++)
                                    {
                                        int             itemIndex = leftSiblingChildren.Items.Count - 1;
                                        PdfDirectObject item      = leftSiblingChildren.Items[itemIndex];
                                        leftSiblingChildren.Items.RemoveAt(itemIndex);
                                        kidChildren.Items.Insert(0, item);
                                    }
                                    // Update left sibling's key limits!
                                    UpdateNodeLimits(leftSiblingChildren);
                                }
                                else if (rightSiblingChildren != null && !rightSiblingChildren.IsUndersized())
                                {
                                    // Move the first child subtree of the right sibling to be the last child subtree of the kid!
                                    for (int index = 0, endIndex = rightSiblingChildren.Info.ItemCount; index < endIndex; index++)
                                    {
                                        int             itemIndex = 0;
                                        PdfDirectObject item      = rightSiblingChildren.Items[itemIndex];
                                        rightSiblingChildren.Items.RemoveAt(itemIndex);
                                        kidChildren.Items.Add(item);
                                    }
                                    // Update right sibling's key limits!
                                    UpdateNodeLimits(rightSiblingChildren);
                                }
                                else
                                {
                                    if (leftSibling != null)
                                    {
                                        // Merging with the left sibling...
                                        for (int index = leftSiblingChildren.Items.Count; index-- > 0;)
                                        {
                                            PdfDirectObject item = leftSiblingChildren.Items[index];
                                            leftSiblingChildren.Items.RemoveAt(index);
                                            kidChildren.Items.Insert(0, item);
                                        }
                                        nodeChildren.Items.RemoveAt(mid - 1);
                                        leftSibling.Reference.Delete();
                                    }
                                    else if (rightSibling != null)
                                    {
                                        // Merging with the right sibling...
                                        for (int index = rightSiblingChildren.Items.Count; index-- > 0;)
                                        {
                                            int             itemIndex = 0;
                                            PdfDirectObject item      = rightSiblingChildren.Items[itemIndex];
                                            rightSiblingChildren.Items.RemoveAt(itemIndex);
                                            kidChildren.Items.Add(item);
                                        }
                                        nodeChildren.Items.RemoveAt(mid + 1);
                                        rightSibling.Reference.Delete();
                                    }
                                    if (nodeChildren.Items.Count == 1)
                                    {
                                        // Collapsing root...
                                        nodeChildren.Items.RemoveAt(0);
                                        for (int index = kidChildren.Items.Count; index-- > 0;)
                                        {
                                            int             itemIndex = 0;
                                            PdfDirectObject item      = kidChildren.Items[itemIndex];
                                            kidChildren.Items.RemoveAt(itemIndex);
                                            nodeChildren.Items.Add(item);
                                        }
                                        kid.Reference.Delete();
                                        kid          = node;
                                        kidReference = kid.Reference;
                                        kidChildren  = nodeChildren;
                                    }
                                }
                                // Update key limits!
                                UpdateNodeLimits(kidChildren);
                            }
                            // Go down one level!
                            nodeReferenceStack.Push(kidReference);
                            node = kid;
                            break;
                        }
                    }
                }
            }
        }