~ubuntu-branches/ubuntu/trusty/pdfmod/trusty

« back to all changes in this revision

Viewing changes to lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-06-18 03:44:46 UTC
  • Revision ID: james.westby@ubuntu.com-20100618034446-bogifrsscpayp361
Tags: upstream-0.8.3
ImportĀ upstreamĀ versionĀ 0.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#region PDFsharp - A .NET library for processing PDF
 
2
//
 
3
// Authors:
 
4
//   Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
 
5
//
 
6
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
 
7
//
 
8
// http://www.pdfsharp.com
 
9
// http://sourceforge.net/projects/pdfsharp
 
10
//
 
11
// Permission is hereby granted, free of charge, to any person obtaining a
 
12
// copy of this software and associated documentation files (the "Software"),
 
13
// to deal in the Software without restriction, including without limitation
 
14
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
15
// and/or sell copies of the Software, and to permit persons to whom the
 
16
// Software is furnished to do so, subject to the following conditions:
 
17
//
 
18
// The above copyright notice and this permission notice shall be included
 
19
// in all copies or substantial portions of the Software.
 
20
//
 
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
22
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
24
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
25
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
26
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 
27
// DEALINGS IN THE SOFTWARE.
 
28
#endregion
 
29
 
 
30
// With this define each iref object gets a unique number (uid) to make them distinguishable in the debugger
 
31
#define UNIQUE_IREF
 
32
 
 
33
using System;
 
34
using System.Diagnostics;
 
35
using System.Collections;
 
36
using System.Text;
 
37
using System.IO;
 
38
using PdfSharp.Internal;
 
39
using PdfSharp.Pdf.IO;
 
40
 
 
41
namespace PdfSharp.Pdf.Advanced
 
42
{
 
43
  /// <summary>
 
44
  /// Represents an indirect reference to a PdfObject.
 
45
  /// </summary>
 
46
  [DebuggerDisplay("iref({ObjectNumber}, {GenerationNumber})")]
 
47
  public sealed class PdfReference : PdfItem
 
48
  {
 
49
    // About PdfReference 
 
50
    // 
 
51
    // * A PdfReference holds the either ObjectID or the PdfObject or both.
 
52
    // 
 
53
    // * Each PdfObject has a PdfReference if and only if it is an indirect object. Direct objects have
 
54
    //   no PdfReference, because they are embedded in a parent objects.
 
55
    //
 
56
    // * PdfReference objects are used to reference PdfObject instances. A value in a PDF dictionary
 
57
    //   or array that is a PdfReference represents an indirect reference. A value in a PDF dictionary or
 
58
    //   or array that is a PdfObject represents a direct (or embeddded) object.
 
59
    //
 
60
    // * When a PDF file is imported, the PdfXRefTable is filled with PdfReference objects keeping the
 
61
    //   ObjectsIDs and file positions (offsets) of all indirect objects.
 
62
    //
 
63
    // * Indirect objects can easily be renumbered because they do not rely on their ObjectsIDs.
 
64
    //
 
65
    // * During modification of a document the ObjectID of an indirect object has no meaning,
 
66
    //   except that they must be different in pairs.
 
67
 
 
68
    /// <summary>
 
69
    /// Initializes a new PdfReference instance for the specified indirect object.
 
70
    /// </summary>
 
71
    public PdfReference(PdfObject pdfObject)
 
72
    {
 
73
      Debug.Assert(pdfObject.Reference == null, "Must not create iref for an object that already has one.");
 
74
      this.value = pdfObject;
 
75
#if UNIQUE_IREF && DEBUG
 
76
      this.uid = ++PdfReference.counter;
 
77
#endif
 
78
    }
 
79
 
 
80
    /// <summary>
 
81
    /// Initializes a new PdfReference instance from the specified object identifier and file position.
 
82
    /// </summary>
 
83
    public PdfReference(PdfObjectID objectID, int position)
 
84
    {
 
85
      this.objectID = objectID;
 
86
      this.position = position;
 
87
#if UNIQUE_IREF && DEBUG
 
88
      this.uid = ++PdfReference.counter;
 
89
#endif
 
90
    }
 
91
 
 
92
    /// <summary>
 
93
    /// Writes the object in PDF iref table format.
 
94
    /// </summary>
 
95
    internal void WriteXRefEnty(PdfWriter writer)
 
96
    {
 
97
      // PDFsharp does not yet support PDF 1.5 object streams.
 
98
 
 
99
      // Each line must be exactly 20 bytes long, otherwise Acrobat repairs the file.
 
100
      string text = String.Format("{0:0000000000} {1:00000} n\n",
 
101
        this.position, this.objectID.GenerationNumber); // this.InUse ? 'n' : 'f');
 
102
      writer.WriteRaw(text);
 
103
    }
 
104
 
 
105
    /// <summary>
 
106
    /// Writes an indirect reference.
 
107
    /// </summary>
 
108
    internal override void WriteObject(PdfWriter writer)
 
109
    {
 
110
      writer.Write(this);
 
111
    }
 
112
 
 
113
    /// <summary>
 
114
    /// Gets or sets the object identifier.
 
115
    /// </summary>
 
116
    public PdfObjectID ObjectID
 
117
    {
 
118
      get { return this.objectID; }
 
119
      set
 
120
      {
 
121
        if (this.objectID != value)
 
122
        {
 
123
          this.objectID = value;
 
124
          if (this.Document != null)
 
125
          {
 
126
            //PdfXRefTable table = this.Document.xrefTable;
 
127
            //table.Remove(this);
 
128
            //this.objectID = value;
 
129
            //table.Add(this);
 
130
          }
 
131
        }
 
132
      }
 
133
    }
 
134
    PdfObjectID objectID;
 
135
 
 
136
    /// <summary>
 
137
    /// Gets the object number of the object identifier.
 
138
    /// </summary>
 
139
    public int ObjectNumber
 
140
    {
 
141
      get { return this.objectID.ObjectNumber; }
 
142
    }
 
143
 
 
144
    /// <summary>
 
145
    /// Gets the generation number of the object identifier.
 
146
    /// </summary>
 
147
    public int GenerationNumber
 
148
    {
 
149
      get { return this.objectID.GenerationNumber; }
 
150
    }
 
151
 
 
152
    /// <summary>
 
153
    /// Gets or sets the file position of the related PdfObject.
 
154
    /// </summary>
 
155
    public int Position
 
156
    {
 
157
      get { return this.position; }
 
158
      set { this.position = value; }
 
159
    }
 
160
    int position;  // I know it should be long, but I have never seen a 2GB PDF file.
 
161
 
 
162
    //public bool InUse
 
163
    //{
 
164
    //  get {return this.inUse;}
 
165
    //  set {this.inUse = value;}
 
166
    //}
 
167
    //bool inUse;
 
168
 
 
169
    /// <summary>
 
170
    /// Gets or sets the referenced PdfObject.
 
171
    /// </summary>
 
172
    public PdfObject Value
 
173
    {
 
174
      get { return this.value; }
 
175
      set
 
176
      {
 
177
        this.value = value;
 
178
        // value must never be null
 
179
        value.Reference = this;
 
180
      }
 
181
    }
 
182
    PdfObject value;
 
183
 
 
184
    /// <summary>
 
185
    /// Hack for dead objects.
 
186
    /// </summary>
 
187
    internal void SetObject(PdfObject value)
 
188
    {
 
189
      this.value = value;
 
190
    }
 
191
 
 
192
    /// <summary>
 
193
    /// Gets or sets the document this object belongs to.
 
194
    /// </summary>
 
195
    public PdfDocument Document
 
196
    {
 
197
      get { return this.document; }
 
198
      set { this.document = value; }
 
199
    }
 
200
    PdfDocument document;
 
201
 
 
202
    /// <summary>
 
203
    /// Gets a string representing the object identifier.
 
204
    /// </summary>
 
205
    public override string ToString()
 
206
    {
 
207
      return this.objectID.ToString() + " R";
 
208
    }
 
209
 
 
210
    internal static PdfReferenceComparer Comparer
 
211
    {
 
212
      get { return new PdfReferenceComparer(); }
 
213
    }
 
214
 
 
215
    /// <summary>
 
216
    /// Implements a comparer that compares PdfReference objects by their PdfObjectID.
 
217
    /// </summary>
 
218
    internal class PdfReferenceComparer : IComparer
 
219
    {
 
220
      public int Compare(object x, object y)
 
221
      {
 
222
        PdfReference l = x as PdfReference;
 
223
        PdfReference r = y as PdfReference;
 
224
        if (l != null)
 
225
        {
 
226
          if (r != null)
 
227
            return l.objectID.CompareTo(r.objectID);
 
228
          else
 
229
            return -1;
 
230
        }
 
231
        else if (r != null)
 
232
          return 1;
 
233
        else
 
234
          return 0;
 
235
      }
 
236
    }
 
237
 
 
238
#if UNIQUE_IREF && DEBUG
 
239
    static int counter = 0;
 
240
    int uid;
 
241
#endif
 
242
  }
 
243
}