Class: HexaPDF::Type::PageTreeNode
- Inherits:
-
Dictionary
- Object
- Object
- Dictionary
- HexaPDF::Type::PageTreeNode
- Defined in:
- lib/hexapdf/type/page_tree_node.rb
Overview
Represents a node in the page tree of the PDF’s document.
The page tree is a tree structure containing page tree nodes for the root and intermediate nodes and page objects for the leaf nodes (see Page). The root node of the page tree is linked via the /Pages entry in the Catalog.
All operations except #add_page on the page tree are rather expensive because page tree nodes and page objects can be mixed. This means that for finding a page at a specific index we have to go through all objects that come before it.
Page indices are zero-based, not one-based. Therefore the first page has an index of 0!
Since the page tree needs a certain structure it is not advised to directly modify page tree nodes. The validation feature can correct most problems but until the page tree is in order the methods may not work correctly!
Newly created pages use the ‘page.default_media_box’ configuration option for the /MediaBox value. If an inherited /Resources dictionary does not exist, an empty one is created for the page.
See: PDF1.7 s7.7.3.2, Page
Constant Summary
Constants included from DictionaryFields
DictionaryFields::Boolean, DictionaryFields::PDFByteString, DictionaryFields::PDFDate
Constants inherited from Object
Object::NOT_DUPLICATABLE_CLASSES
Instance Attribute Summary
Attributes inherited from Object
#data, #document, #must_be_indirect
Instance Method Summary collapse
-
#add_page(page = nil) ⇒ Object
Adds the page or a new empty page at the end and returns it.
-
#delete_page(index) ⇒ Object
Deletes the page at the position specified by the zero-based index and returns it.
-
#each_page(&block) ⇒ Object
:call-seq: pages.each_page {|page| block } -> pages pages.each_page -> Enumerator.
-
#insert_page(index, page = nil) ⇒ Object
Inserts the page or a new empty page at the zero-based index and returns it.
-
#must_be_indirect? ⇒ Boolean
Returns
true
since page tree objects must always be indirect. -
#page(index) ⇒ Object
Returns the page for the zero-based index or
nil
if no such page exists. -
#page_count ⇒ Object
Returns the number of pages under this page tree.
Methods inherited from Dictionary
#[], #[]=, define_field, #delete, #each, each_field, #empty?, field, #key?, #to_hash, #type
Methods inherited from Object
#<=>, #==, #deep_copy, deep_copy, #document?, #eql?, #gen, #gen=, #hash, #indirect?, #initialize, #inspect, #null?, #oid, #oid=, #type, #validate, #value, #value=
Constructor Details
This class inherits a constructor from HexaPDF::Object
Instance Method Details
#add_page(page = nil) ⇒ Object
Adds the page or a new empty page at the end and returns it.
150 151 152 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 150 def add_page(page = nil) insert_page(-1, page) end |
#delete_page(index) ⇒ Object
Deletes the page at the position specified by the zero-based index and returns it. If an invalid index is specified, nil
is returned.
Negative indices count backwards from the end, i.e. -1 is the last page.
Must be called on the root of the page tree, otherwise the /Count entries are not correctly updated!
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 161 def delete_page(index) index = self[:Count] + index if index < 0 return nil if index < 0 || index >= self[:Count] page = nil self[:Count] -= 1 self[:Kids].each_with_index do |kid, kid_index| kid = document.deref(kid) if kid.type == :Page && index == 0 page = self[:Kids].delete_at(kid_index) document.delete(page) break elsif kid.type == :Page index -= 1 elsif index < kid[:Count] page = kid.delete_page(index) if kid[:Count] == 0 self[:Kids].delete_at(kid_index) document.delete(kid) elsif kid[:Count] == 1 self[:Kids][kid_index] = kid[:Kids][0] kid[:Kids][0][:Parent] = self document.delete(kid) end break else index -= kid[:Count] end end page end |
#each_page(&block) ⇒ Object
:call-seq:
pages.each_page {|page| block } -> pages
pages.each_page -> Enumerator
Iterates over all pages that are beneath this page tree node, from the first to the last page.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 200 def each_page(&block) return to_enum(__method__) unless block_given? self[:Kids].each do |kid| kid = document.deref(kid) if kid.type == :Page yield(kid) else kid.each_page(&block) end end self end |
#insert_page(index, page = nil) ⇒ Object
Inserts the page or a new empty page at the zero-based index and returns it.
Negative indices count backwards from the end, i.e. -1 is the last page. When using negative indices, the page will be inserted after that element. So using an index of -1 will insert the page after the last page.
Must be called on the root of the page tree, otherwise the /Count entries are not correctly updated!
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 118 def insert_page(index, page = nil) page ||= new_page index = self[:Count] + index + 1 if index < 0 if index >= self[:Count] self[:Kids] << page page[:Parent] = self page[:Resources] ||= {} else self[:Kids].each_with_index do |kid, kid_index| kid = document.deref(kid) if index == 0 self[:Kids].insert(kid_index, page) page[:Parent] = self break elsif kid.type == :Page index -= 1 elsif index <= kid[:Count] kid.insert_page(index, page) break else index -= kid[:Count] end end end self[:Count] += 1 page end |
#must_be_indirect? ⇒ Boolean
Returns true
since page tree objects must always be indirect.
75 76 77 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 75 def must_be_indirect? true end |
#page(index) ⇒ Object
Returns the page for the zero-based index or nil
if no such page exists.
Negative indices count backwards from the end, i.e. -1 is the last page.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 90 def page(index) index = self[:Count] + index if index < 0 return nil if index < 0 || index >= self[:Count] self[:Kids].each do |kid| kid = document.deref(kid) if kid.type == :Page if index == 0 return kid else index -= 1 end elsif index < kid[:Count] return kid.page(index) else index -= kid[:Count] end end end |
#page_count ⇒ Object
Returns the number of pages under this page tree.
Note: If this methods is not called on the root object of the page tree, the returned number is not the total number of pages in the document!
83 84 85 |
# File 'lib/hexapdf/type/page_tree_node.rb', line 83 def page_count self[:Count] end |