pdf-writer 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/ChangeLog +44 -0
  2. data/LICENCE +118 -0
  3. data/README +32 -0
  4. data/bin/loader +54 -0
  5. data/bin/manual +22 -0
  6. data/bin/manual.bat +2 -0
  7. data/demo/chunkybacon.rb +28 -0
  8. data/demo/code.rb +63 -0
  9. data/demo/colornames.rb +843 -0
  10. data/demo/demo.rb +65 -0
  11. data/demo/gettysburg.rb +58 -0
  12. data/demo/hello.rb +18 -0
  13. data/demo/individual-i.rb +81 -0
  14. data/demo/pac.rb +62 -0
  15. data/demo/pagenumber.rb +67 -0
  16. data/demo/qr-language.rb +573 -0
  17. data/demo/qr-library.rb +371 -0
  18. data/images/chunkybacon.jpg +0 -0
  19. data/images/chunkybacon.png +0 -0
  20. data/images/pdfwriter-icon.jpg +0 -0
  21. data/images/pdfwriter-small.jpg +0 -0
  22. data/lib/pdf/charts.rb +13 -0
  23. data/lib/pdf/charts/stddev.rb +431 -0
  24. data/lib/pdf/grid.rb +135 -0
  25. data/lib/pdf/math.rb +108 -0
  26. data/lib/pdf/quickref.rb +330 -0
  27. data/lib/pdf/simpletable.rb +946 -0
  28. data/lib/pdf/techbook.rb +890 -0
  29. data/lib/pdf/writer.rb +2661 -0
  30. data/lib/pdf/writer/arc4.rb +63 -0
  31. data/lib/pdf/writer/fontmetrics.rb +201 -0
  32. data/lib/pdf/writer/fonts/Courier-Bold.afm +342 -0
  33. data/lib/pdf/writer/fonts/Courier-BoldOblique.afm +342 -0
  34. data/lib/pdf/writer/fonts/Courier-Oblique.afm +342 -0
  35. data/lib/pdf/writer/fonts/Courier.afm +342 -0
  36. data/lib/pdf/writer/fonts/Helvetica-Bold.afm +2827 -0
  37. data/lib/pdf/writer/fonts/Helvetica-BoldOblique.afm +2827 -0
  38. data/lib/pdf/writer/fonts/Helvetica-Oblique.afm +3051 -0
  39. data/lib/pdf/writer/fonts/Helvetica.afm +3051 -0
  40. data/lib/pdf/writer/fonts/MustRead.html +1 -0
  41. data/lib/pdf/writer/fonts/Symbol.afm +213 -0
  42. data/lib/pdf/writer/fonts/Times-Bold.afm +2588 -0
  43. data/lib/pdf/writer/fonts/Times-BoldItalic.afm +2384 -0
  44. data/lib/pdf/writer/fonts/Times-Italic.afm +2667 -0
  45. data/lib/pdf/writer/fonts/Times-Roman.afm +2419 -0
  46. data/lib/pdf/writer/fonts/ZapfDingbats.afm +225 -0
  47. data/lib/pdf/writer/graphics.rb +727 -0
  48. data/lib/pdf/writer/graphics/imageinfo.rb +365 -0
  49. data/lib/pdf/writer/lang.rb +43 -0
  50. data/lib/pdf/writer/lang/en.rb +77 -0
  51. data/lib/pdf/writer/object.rb +23 -0
  52. data/lib/pdf/writer/object/action.rb +40 -0
  53. data/lib/pdf/writer/object/annotation.rb +42 -0
  54. data/lib/pdf/writer/object/catalog.rb +39 -0
  55. data/lib/pdf/writer/object/contents.rb +68 -0
  56. data/lib/pdf/writer/object/destination.rb +40 -0
  57. data/lib/pdf/writer/object/encryption.rb +53 -0
  58. data/lib/pdf/writer/object/font.rb +76 -0
  59. data/lib/pdf/writer/object/fontdescriptor.rb +34 -0
  60. data/lib/pdf/writer/object/fontencoding.rb +39 -0
  61. data/lib/pdf/writer/object/image.rb +168 -0
  62. data/lib/pdf/writer/object/info.rb +55 -0
  63. data/lib/pdf/writer/object/outline.rb +30 -0
  64. data/lib/pdf/writer/object/outlines.rb +30 -0
  65. data/lib/pdf/writer/object/page.rb +195 -0
  66. data/lib/pdf/writer/object/pages.rb +115 -0
  67. data/lib/pdf/writer/object/procset.rb +46 -0
  68. data/lib/pdf/writer/object/viewerpreferences.rb +74 -0
  69. data/lib/pdf/writer/ohash.rb +58 -0
  70. data/lib/pdf/writer/oreader.rb +25 -0
  71. data/lib/pdf/writer/state.rb +48 -0
  72. data/lib/pdf/writer/strokestyle.rb +138 -0
  73. data/manual.pwd +5151 -0
  74. metadata +147 -0
@@ -0,0 +1,168 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: image.rb,v 1.2 2005/05/16 03:59:21 austin Exp $
10
+ #++
11
+ require 'pdf/writer/oreader'
12
+
13
+ # an image object, will be an XObject in the document, includes description and data
14
+ class PDF::Writer::External::Image < PDF::Writer::External
15
+ attr_reader :label
16
+ attr_reader :image_info
17
+
18
+ def initialize(parent, data, image, label)
19
+ super(parent)
20
+
21
+ @data = data
22
+
23
+ @image_info = image
24
+
25
+ @info = {
26
+ 'Type' => '/XObject',
27
+ 'Subtype' => '/Image',
28
+ 'Width' => image.width,
29
+ 'Height' => image.height
30
+ }
31
+
32
+ case image.format
33
+ when "JPEG"
34
+ case image.channels
35
+ when 1
36
+ @info['ColorSpace'] = '/DeviceGray'
37
+ when 4
38
+ @info['ColorSpace'] = '/DeviceCMYK'
39
+ # This should fix problems with CMYK JPEG colours inverted in
40
+ # Adobe Acrobat. Enable only if appropriate.
41
+ # @info['Decode'] = '[1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0]'
42
+ else
43
+ @info['ColorSpace'] = '/DeviceRGB'
44
+ end
45
+ @info['Filter'] = '/DCTDecode'
46
+ @info['BitsPerComponent'] = 8
47
+ when "PNG"
48
+ if image.info[:compression_method] != 0
49
+ raise TypeError, PDF::Writer::Message[:png_unsupp_compres]
50
+ end
51
+
52
+ if image.info[:filter_method] != 0
53
+ raise TypeError, PDF::Writer::Message[:png_unsupp_filter]
54
+ end
55
+
56
+ data = data.dup
57
+ data.extend(PDF::Writer::OffsetReader)
58
+
59
+ data.read_o(8) # Skip the default header
60
+
61
+ ok = true
62
+ length = data.size
63
+ palette = ""
64
+ idat = ""
65
+
66
+ while ok
67
+ chunk_size = data.read_o(4).unpack("N")[0]
68
+ section = data.read_o(4)
69
+ case section
70
+ when 'PLTE'
71
+ palette << data.read_o(chunk_size)
72
+ when 'IDAT'
73
+ idat << data.read_o(chunk_size)
74
+ when 'tRNS'
75
+ # This chunk can only occur once and it must occur after the
76
+ # PLTE chunk and before the IDAT chunk
77
+ trans = {}
78
+ case image.info[:color_type]
79
+ when 3
80
+ # Indexed colour, RGB. Each byte in this chunk is an alpha for
81
+ # the palette index in the PLTE ("palette") chunk up until the
82
+ # last non-opaque entry. Set up an array, stretching over all
83
+ # palette entries which will be 0 (opaque) or 1 (transparent).
84
+ trans[:type] = 'indexed'
85
+ trans[:data] = data.read_o(chunk_size).unpack("C*")
86
+ when 0
87
+ # Greyscale. Corresponding to entries in the PLTE chunk.
88
+ # Grey is two bytes, range 0 .. (2 ^ bit-depth) - 1
89
+ trans[:grayscale] = data.read_o(2).unpack("n")
90
+ trans[:type] = 'indexed'
91
+ trans[:data] = data.read_o.unpack("C")
92
+ when 2
93
+ # True colour with proper alpha channel.
94
+ trans[:rgb] = data.read_o(6).unpack("nnn")
95
+ end
96
+ else
97
+ data.offset += chunk_size
98
+ end
99
+
100
+ ok = section != "IEND"
101
+
102
+ data.read_o(4) # Skip the CRC
103
+ end
104
+
105
+ if image.bits > 8
106
+ raise TypeError, PDF::Writer::Message[:png_8bit_colour]
107
+ end
108
+ if image.info[:interlace_method] != 0
109
+ raise TypeError, PDF::Writer::Message[:png_interlace]
110
+ end
111
+
112
+ ncolor = 1
113
+ colour = 'DeviceRGB'
114
+ case image.info[:color_type]
115
+ when 3
116
+ nil
117
+ when 2
118
+ ncolor = 3
119
+ when 0
120
+ colour = 'DeviceGray'
121
+ else
122
+ raise TypeError, PDF::Writer::Message[:png_alpha_trans]
123
+ end
124
+
125
+ @info['Filter'] = '[/FlateDecode]'
126
+ @info['DecodeParms'] = "[<</Predictor 15 /Colors #{ncolor} /Columns #{image.width}>>]"
127
+ @info['BitsPerComponent'] = image.bits.to_s
128
+
129
+ unless palette.empty?
130
+ @info['ColorSpace'] = " [ /Indexed /DeviceRGB #{(palette.size / 3) - 1} "
131
+ contents = PDF::Writer::Contents.new
132
+ contents.data = palette
133
+ @info['ColorSpace'] << "#{contents.oid} 0 R ]"
134
+
135
+ if trans
136
+ case trans[:type]
137
+ when 'indexed'
138
+ @info['Mask'] = " [ #{trans[:data].join(' ')} ] "
139
+ end
140
+ end
141
+ else
142
+ @info['ColorSpace'] = "/#{colour}"
143
+ end
144
+
145
+ @data = idat
146
+ end
147
+
148
+ @label = label
149
+
150
+ # assign it a place in the named resource dictionary as an external
151
+ # object, according to the label passed in with it.
152
+ @parent.pages << self
153
+ # also make sure that we have the right procset object for it.
154
+ @parent.procset << 'ImageC'
155
+ end
156
+
157
+ def to_s
158
+ tmp = @data.dup
159
+ res = "\n#{@oid} 0 obj\n<<"
160
+ @info.each { |k, v| res << "\n/#{k} #{v}"}
161
+ if (@parent.encrypted?)
162
+ @parent.arc4.prepare(self)
163
+ tmp = @parent.arc4.encrypt(tmp)
164
+ end
165
+ res << "\n/Length #{tmp.size} >>\nstream\n#{tmp}\nendstream\nendobj\n"
166
+ res
167
+ end
168
+ end
@@ -0,0 +1,55 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: info.rb,v 1.4 2005/05/25 21:18:08 austin Exp $
10
+ #++
11
+ # Define the document information -- metadata.
12
+ class PDF::Writer::Object::Info < PDF::Writer::Object
13
+ Info = %w{CreationDate Creator Title Author Subject Keywords ModDate Trapped Producer}
14
+ def initialize(parent)
15
+ super(parent)
16
+
17
+ @parent.instance_variable_set('@info', self)
18
+ @creationdate = Time.now
19
+
20
+ @creator = File.basename($0)
21
+ @producer = "PDF::Writer for Ruby"
22
+ @title = nil
23
+ @author = nil
24
+ @subject = nil
25
+ @keywords = nil
26
+ @moddate = nil
27
+ @trapped = nil
28
+ end
29
+
30
+ Info.each do |i|
31
+ attr_accessor i.downcase.intern
32
+ end
33
+
34
+ def to_s
35
+ @parent.arc4.prepare(self) if @parent.encrypted?
36
+ res = "\n#{@oid} 0 obj\n<<\n"
37
+ Info.each do |i|
38
+ v = __send__("#{i.downcase}".intern)
39
+ next if v.nil?
40
+ res << "/#{i} ("
41
+ if v.kind_of?(Time)
42
+ s = "D:%04d%02d%02d%02d%02d"
43
+ v = v.utc
44
+ v = s % [ v.year, v.month, v.day, v.hour, v.min ]
45
+ end
46
+ if @parent.encrypted?
47
+ res << PDF::Writer.escape(@parent.arc4.encrypt(v))
48
+ else
49
+ res << PDF::Writer.escape(v)
50
+ end
51
+ res << ")\n"
52
+ end
53
+ res << ">>\nendobj"
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: outline.rb,v 1.2 2005/05/16 03:59:21 austin Exp $
10
+ #++
11
+ # Define the outlines in the doc, empty for now
12
+ class PDF::Writer::Object::Outline < PDF::Writer::Object
13
+ def initialize(parent, label, title = label)
14
+ super(parent)
15
+
16
+ @action = PDF::Writer::Action.new(parent, label, :ilink)
17
+ @title = title
18
+
19
+ parent.outlines.list << self
20
+ end
21
+
22
+ def to_s
23
+ pos = @parent.outlines.list.index(self)
24
+ res = "\n#{@oid} 0 obj\n<< /Title (#{@title})"
25
+ res << " /Prev #{@parent.outlines.list[pos - 1].oid} 0 R" if pos.nonzero?
26
+ res << " /Next #{@parent.outlines.list[pos + 1].oid} 0 R" if @oid != parent.outlines.list[-1].oid
27
+ res << " /A #{@action.oid} 0 R>>\nendobj"
28
+ res
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: outlines.rb,v 1.2 2005/05/16 03:59:21 austin Exp $
10
+ #++
11
+ # Define the outlines in the doc, empty for now
12
+ class PDF::Writer::Object::Outlines < PDF::Writer::Object
13
+ def initialize(parent)
14
+ super(parent)
15
+
16
+ @list = []
17
+ @parent.catalog.outlines = self
18
+ end
19
+
20
+ attr_reader :list
21
+
22
+ def to_s
23
+ if @list.empty?
24
+ "\n#{@oid} 0 obj\n<< /Type /Outlines >>\nendobj"
25
+ else
26
+ "\n#{@oid} 0 obj\n<< /Type /Outlines /First #{@list[0].oid} 0 R /Last
27
+ #{@list[-1].oid} 0 R>>\nendobj"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,195 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: page.rb,v 1.3 2005/06/02 21:20:35 austin Exp $
10
+ #++
11
+ # A page object, it also creates a contents object to hold its contents
12
+ class PDF::Writer::Object::Page < PDF::Writer::Object
13
+ # Create a page. The optional +relative+ is a Hash with keys :pos =>
14
+ # :before|:after and :rpage, the page to which this new page will be
15
+ # added relative.
16
+ def initialize(parent, relative = nil)
17
+ super(parent)
18
+
19
+ @parent.current_page = self
20
+ @owner = @parent.instance_variable_get('@current_node')
21
+ @page_number = @parent.pages.size
22
+ @contents = []
23
+
24
+ if relative.nil?
25
+ @parent.pages << self
26
+ else
27
+ relative[:page] = self
28
+ @parent.pages.add(relative)
29
+ end
30
+
31
+ # make a contents object to go with this page
32
+ @contents << PDF::Writer::Object::Contents.new(@parent, self)
33
+ @parent.instance_variable_set('@current_contents', @contents[-1])
34
+ match = (@parent.pages.size % 2 == 0 ? :even_pages : :odd_pages)
35
+ # Cheat here. I don't want to add an unnecessary attribute.
36
+ @parent.instance_variable_get('@add_loose_objects').each do |obj, target|
37
+ @contents << obj if target == :all_pages or match == target
38
+ end
39
+
40
+ @annotations = []
41
+
42
+ @media_box = nil
43
+ @crop_box = nil
44
+ @bleed_box = nil
45
+ @trim_box = nil
46
+ @art_box = nil
47
+ end
48
+
49
+ attr_accessor :contents
50
+ attr_reader :page_number
51
+
52
+ def add_annotation(a)
53
+ @annotations << a
54
+ end
55
+
56
+ def to_s
57
+ res = "\n#{@oid} 0 obj\n<< /Type /Page\n/Parent #{@owner.oid} 0 R"
58
+ unless @annotations.empty?
59
+ res << "\n/Annots ["
60
+ @annotations.each { |e| res << " #{e.oid} 0 R"}
61
+ res << "]"
62
+ end
63
+
64
+ if @contents.size == 1
65
+ res << "\n/Contents #{@contents[0].oid} 0 R"
66
+ else
67
+ res << "\n/Contents [\n"
68
+ @contents.each { |c| res << "#{c.oid} 0 R\n" }
69
+ res << "]"
70
+ end
71
+
72
+ # MediaBox:: rectangle (Required; inheritable). A rectangle (see
73
+ # Section 3.8.4, �Rectangles�), expressed in default user
74
+ # space units, defining the boundaries of the physical
75
+ # medium on which the page is intended to be displayed or
76
+ # printed (see Section 10.10.1, �Page Boundaries�).
77
+ res << "\n/MediaBox [#{@media_box.join(' ')}]" unless @media_box.nil? or @media_box.empty?
78
+ # CropBox:: rectangle (Optional; inheritable) A rectangle, expressed
79
+ # in default user space units, defining the visible region
80
+ # of default user space. When the page is displayed or
81
+ # printed, its contents are to be clipped (cropped) to
82
+ # this rectangle and then imposed on the output medium in
83
+ # some implementation-defined manner (see Section 10.10.1,
84
+ # �Page Boundaries�). Default value: the value of MediaBox.
85
+ res << "\n/CropBox [#{@crop_box.join(' ')}]" unless @crop_box.nil? or @crop_box.empty?
86
+ # BleedBox:: rectangle (Optional; PDF 1.3) A rectangle, expressed in
87
+ # default user space units, defining the region to which
88
+ # the contents of the page should be clipped when output
89
+ # in a production environment (see Section 10.10.1, �Page
90
+ # Boundaries�). Default value: the value of CropBox.
91
+ res << "\n/BleedBox [#{@bleed_box.join(' ')}]" unless @bleed_box.nil? or @bleed_box.empty?
92
+ # TrimBox:: rectangle (Optional; PDF 1.3) A rectangle, expressed in
93
+ # default user space units, defining the intended
94
+ # dimensions of the finished page after trimming (see
95
+ # Section 10.10.1, �Page Boundaries�). Default value: the
96
+ # value of CropBox.
97
+ res << "\n/TrimBox [#{@trim_box.join(' ')}]" unless @trim_box.nil? or @trim_box.empty?
98
+ # ArtBox:: rectangle (Optional; PDF 1.3) A rectangle, expressed in
99
+ # default user space units, defining the extent of the
100
+ # page�s meaningful content (including potential white
101
+ # space) as intended by the page�s creator (see Section
102
+ # 10.10.1, �Page Boundaries�). Default value: the value of
103
+ # CropBox.
104
+ res << "\n/ArtBox [#{@art_box.join(' ')}]" unless @art_box.nil? or @art_box.empty?
105
+
106
+ res << "\n>>\nendobj"
107
+ end
108
+ end
109
+
110
+ # BoxColorInfo:: dictionary (Optional; PDF 1.4) A box color information
111
+ # dictionary specifying the colors and other visual
112
+ # characteristics to be used in displaying guidelines on
113
+ # the screen for the various page boundaries (see �Display
114
+ # of Page Boundaries� on page 893). If this entry is
115
+ # absent, the application should use its own current
116
+ # default settings.
117
+ #
118
+ # Rotate:: integer (Optional; inheritable) The number of degrees by
119
+ # which the page should be rotated clockwise when
120
+ # displayed or printed. The value must be a multiple of
121
+ # 90. Default value: 0.
122
+ # Group:: dictionary (Optional; PDF 1.4) A group attributes
123
+ # dictionary specifying the attributes of the page�s page
124
+ # group for use in the transparent imaging model (see
125
+ # Sections 7.3.6, �Page Group,� and 7.5.5, �Transparency
126
+ # Group XObjects�).
127
+ # Thumb:: stream (Optional) A stream object defining the page�s
128
+ # thumbnail image (see Section 8.2.3, �Thumbnail Images�).
129
+ # B:: array (Optional; PDF 1.1; recommended if the page
130
+ # contains article beads) An array of indirect references
131
+ # to article beads appearing on the page (see Section
132
+ # 8.3.2, �Articles�; see also implementation note 37 in
133
+ # Appendix H). The beads are listed in the array in
134
+ # natural reading order.
135
+ # Dur:: number (Optional; PDF 1.1) The page�s display duration
136
+ # (also called its advance timing): the maximum length of
137
+ # time, in seconds, that the page is displayed during
138
+ # presentations before the viewer application
139
+ # automatically advances to the next page (see Section
140
+ # 8.3.3, �Presentations�). By default, the viewer does not
141
+ # advance automatically.
142
+ # Trans:: dictionary (Optional; PDF 1.1) A transition dictionary
143
+ # describing the transition effect to be used when
144
+ # displaying the page during presentations (see Section
145
+ # 8.3.3, �Presentations�).
146
+ # Annots:: array (Optional) An array of annotation dictionaries
147
+ # representing annotations associated with the page (see
148
+ # Section 8.4, �Annotations�).
149
+ # AA:: dictionary (Optional; PDF 1.2) An additional-actions
150
+ # dictionary defining actions to be performed when the
151
+ # page is opened or closed (see Section 8.5.2, �Trigger
152
+ # Events�; see also implementation note 38 in Appendix H).
153
+ # Metadata:: stream (Optional; PDF 1.4) A metadata stream containing
154
+ # metadata for the page (see Section 10.2.2, �Metadata
155
+ # Streams�).
156
+ # PieceInfo:: dictionary (Optional; PDF 1.3) A page-piece dictionary
157
+ # associated with the page (see Section 10.4, �Page-Piece
158
+ # Dictionaries�).
159
+ # StructParents:: integer (Required if the page contains structural
160
+ # content items; PDF 1.3) The integer key of the page�s
161
+ # entry in the structural parent tree (see �Finding
162
+ # Structure Elements from Content Items� on page 797).
163
+ # ID:: string (Optional; PDF 1.3; indirect reference preferred)
164
+ # The digital identifier of the page�s parent Web Capture
165
+ # content set (see Section 10.9.5, �Object Attributes
166
+ # Related to Web Capture�).
167
+ # PZ:: number (Optional; PDF 1.3) The page�s preferred zoom
168
+ # (magnification) factor: the factor by which it should be
169
+ # scaled to achieve the natural display magnification (see
170
+ # Section 10.9.5, �Object Attributes Related to Web
171
+ # Capture�).
172
+ # SeparationInfo:: dictionary (Optional; PDF 1.3) A separation dictionary
173
+ # containing information needed to generate color
174
+ # separations for the page (see Section 10.10.3,
175
+ # �Separation Dictionaries�).
176
+ # Tabs:: name (Optional; PDF 1.5) A name specifying the tab order
177
+ # to be used for annotations on the page. The possible
178
+ # values are R (row order), C (column order), and S
179
+ # (structure order). See Section 8.4, �Annotations,� for
180
+ # details.
181
+ # TemplateInstantiated:: name (Required if this page was created from a
182
+ # named page object; PDF 1.5) The name of the
183
+ # originating page object (see Section 8.6.5,
184
+ # �Named Pages�).
185
+ # PresSteps:: dictionary (Optional; PDF 1.5) A navigation node
186
+ # dictionary representing the first node on the page (see
187
+ # �Sub-page Navigation� on page 566).
188
+ # UserUnit:: number (Optional; PDF 1.6) A positive number giving the
189
+ # size of default user space units, in multiples of 1/72
190
+ # inch. The range of supported values is
191
+ # implementation-dependent; see implementation note 171 in
192
+ # Appendix H. Default value: 1.0 (user unit is 1/72 inch).
193
+ # VP:: dictionary (Optional; PDF 1.6) An array of viewport
194
+ # dictionaries (see Table 8.105) specifying rectangular
195
+ # regions of the page.