Class: Pdfrb::Document::Pages

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/pdfrb/document/pages.rb

Overview

Page-tree facade. Exposes add, [], each, count, delete against the Catalog's /Pages tree.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document) ⇒ Pages

Returns a new instance of Pages.



12
13
14
# File 'lib/pdfrb/document/pages.rb', line 12

def initialize(document)
  @document = document
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



10
11
12
# File 'lib/pdfrb/document/pages.rb', line 10

def document
  @document
end

Instance Method Details

#[](index) ⇒ Object



78
79
80
81
# File 'lib/pdfrb/document/pages.rb', line 78

def [](index)
  each_with_index { |p, i| return p if i == index }
  nil
end

#add(media_box: nil, rotate: 0, width: nil, height: nil, bleed_box: nil, trim_box: nil, art_box: nil, crop_box: nil) ⇒ Object Also known as: <<

Add a new page at the end of the page tree.

Options:

media_box: [0, 0, 612, 792]   # default US Letter
rotate: 0                     # degrees

Returns the new Model::Type::Page.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/pdfrb/document/pages.rb', line 23

def add(media_box: nil, rotate: 0, width: nil, height: nil,
       bleed_box: nil, trim_box: nil, art_box: nil, crop_box: nil)
  media_box ||= (width && height ? [0, 0, width, height] : [0, 0, 612, 792])
  media_box ||= (width && height ? [0, 0, width, height] : [0, 0, 612, 792])
  root = pages_root
  contents = document.add({}, type: Pdfrb::Model::Cos::Stream)
  # No eager /Resources: an empty page-level dict would override
  # the inheritable root resources (s7.7.3.2). The canvas seeds
  # one lazily when it attaches XObjects.
  page_hash = {
    Type: :Page,
    Parent: Pdfrb::Model::Reference.new(root.oid, root.gen),
    MediaBox: media_box,
    Contents: Pdfrb::Model::Reference.new(contents.oid, 0)
  }
  page_hash[:BleedBox] = bleed_box if bleed_box
  page_hash[:TrimBox] = trim_box if trim_box
  page_hash[:ArtBox] = art_box if art_box
  page_hash[:CropBox] = crop_box if crop_box
  page = document.add(page_hash, type: Pdfrb::Model::Type::Page)
  page.value[:Rotate] = rotate if rotate.nonzero?
  kids = (root.value[:Kids] ||= [])
  kids << Pdfrb::Model::Reference.new(page.oid, page.gen)
  root.value[:Count] = (root.value[:Count] || 0) + 1
  page
end

#countObject Also known as: size, length



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/pdfrb/document/pages.rb', line 58

def count
  raw = pages_root[:Count]
  resolved = raw.is_a?(Pdfrb::Model::Reference) ? document.object(raw)&.value : raw
  case resolved
  when Integer then resolved
  when Numeric then resolved.to_i
  else
    # Fallback: walk the page tree.
    count = 0
    each { count += 1 }
    count
  end
end

#delete(page) ⇒ Object



83
84
85
86
87
88
89
90
91
# File 'lib/pdfrb/document/pages.rb', line 83

def delete(page)
  ref = ref_to(page)
  root = pages_root
  kids = root.value[:Kids]
  return unless kids&.delete(ref)

  root.value[:Count] = (root.value[:Count] || 1) - 1
  page
end

#delete_at(index) ⇒ Object

Delete the page at index (0-based).



94
95
96
97
98
99
# File 'lib/pdfrb/document/pages.rb', line 94

def delete_at(index)
  page = self[index]
  return nil unless page

  delete(page)
end

#eachObject



51
52
53
54
55
56
# File 'lib/pdfrb/document/pages.rb', line 51

def each(&)
  return enum_for(:each) unless block_given?

  walk(pages_root, &)
  self
end

#each_with_indexObject

Iterate pages with index.



129
130
131
132
133
134
135
136
137
# File 'lib/pdfrb/document/pages.rb', line 129

def each_with_index(&)
  return enum_for(:each_with_index) unless block_given?

  i = 0
  each do |page|
    yield page, i
    i += 1
  end
end

#empty?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/pdfrb/document/pages.rb', line 74

def empty?
  count.zero?
end

#move(from, to) ⇒ Object

Move a page from one position to another.

Parameters:

  • from (Integer)

    source index (0-based).

  • to (Integer)

    destination index (0-based).



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/pdfrb/document/pages.rb', line 110

def move(from, to)
  return self if from == to

  root = pages_root
  kids = root.value[:Kids]
  return self unless kids.is_a?(::Array)

  page = self[from]
  return self unless page

  ref = ref_to(page)
  kids.delete(ref)
  # Clamp to valid range after deletion.
  insert_at = to > from ? to - 1 : to
  kids.insert(insert_at, ref)
  self
end

#pages_rootObject

The page-tree root (Catalog /Pages), seeding an empty tree if needed. Resources placed here are inherited by every page (s7.7.3.2).

Raises:



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pdfrb/document/pages.rb', line 142

def pages_root
  catalog = document.catalog
  raise Pdfrb::Error, "Document has no Catalog" unless catalog

  ref = catalog.value[:Pages]
  return document.object(ref) if ref

  # No /Pages yet — seed an empty tree.
  root = document.add({ Type: :Pages, Kids: [], Count: 0 },
                      type: Pdfrb::Model::Type::PageTreeNode)
  catalog.value[:Pages] = Pdfrb::Model::Reference.new(root.oid, root.gen)
  root
end

#rotate(angle) ⇒ Object

Set /Rotate on every page. angle must be 0, 90, 180, or 270.



102
103
104
105
# File 'lib/pdfrb/document/pages.rb', line 102

def rotate(angle)
  each { |page| page.value[:Rotate] = angle }
  self
end