Class: Prawn::Core::ObjectStore

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/prawn/core/object_store.rb

Overview

:nodoc:

Constant Summary collapse

BASE_OBJECTS =
%w[info pages root]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ ObjectStore

Returns a new instance of ObjectStore.



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/prawn/core/object_store.rb', line 21

def initialize(opts = {})
  @objects = {}
  @identifiers = []

  load_file(opts[:template]) if opts[:template]

  @info  ||= ref(opts[:info] || {}).identifier
  @root  ||= ref(:Type => :Catalog).identifier
  if pages.nil?
    root.data[:Pages] = ref(:Type => :Pages, :Count => 0, :Kids => [])
  end
end

Instance Attribute Details

#min_versionObject (readonly)

Returns the value of attribute min_version.



17
18
19
# File 'lib/prawn/core/object_store.rb', line 17

def min_version
  @min_version
end

Instance Method Details

#[](id) ⇒ Object



78
79
80
# File 'lib/prawn/core/object_store.rb', line 78

def [](id)
  @objects[id]
end

#compactObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/prawn/core/object_store.rb', line 87

def compact
  # Clear live markers
  each { |o| o.live = false }

  # Recursively mark reachable objects live, starting from the roots
  # (the only objects referenced in the trailer)
  root.mark_live
  info.mark_live

  # Renumber live objects to eliminate gaps (shrink the xref table)
  if @objects.any?{ |_, o| !o.live }
    new_id = 1
    new_objects = {}
    new_identifiers = []

    each do |obj|
      if obj.live
        obj.identifier = new_id
        new_objects[new_id] = obj
        new_identifiers << new_id
        new_id += 1
      end
    end

    @objects = new_objects
    @identifiers = new_identifiers
  end
end

#eachObject



72
73
74
75
76
# File 'lib/prawn/core/object_store.rb', line 72

def each
  @identifiers.each do |id|
    yield @objects[id]
  end
end

#import_page(input, page_num) ⇒ Object

imports all objects required to render a page from another PDF. The objects are added to the current object store, but NOT linked anywhere.

The object ID of the root Page object is returned, it’s up to the calling code to link that into the document structure somewhere. If this isn’t done the imported objects will just be removed when the store is compacted.

Imports nothing and returns nil if the requested page number doesn’t exist. page_num is 1 indexed, so 1 indicates the first page.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/prawn/core/object_store.rb', line 144

def import_page(input, page_num)
  @loaded_objects = {}
  
  io = if input.respond_to?(:seek) && input.respond_to?(:read)
    input
  elsif File.file?(input.to_s)
    if File.respond_to?(:binread)
      StringIO.new(File.binread(input.to_s))
    else
      StringIO.new(File.read(input.to_s))
    end
  else
    raise ArgumentError, "input must be an IO-like object or a filename"
  end

  # unless File.file?(filename)
  #   raise ArgumentError, "#{filename} does not exist"
  # end

  hash = PDF::Reader::ObjectHash.new(io)
  ref  = hash.page_references[page_num - 1]

  ref.nil? ? nil : load_object_graph(hash, ref).identifier

rescue PDF::Reader::MalformedPDFError, PDF::Reader::InvalidObjectError
  msg = "Error reading template file. If you are sure it's a valid PDF, it may be a bug."
  raise Prawn::Errors::TemplateError, msg
rescue PDF::Reader::UnsupportedFeatureError
  msg = "Template file contains unsupported PDF features"
  raise Prawn::Errors::TemplateError, msg
end

#infoObject



38
39
40
# File 'lib/prawn/core/object_store.rb', line 38

def info
  @objects[@info]
end

#object_id_for_page(k) ⇒ Object

returns the object ID for a particular page in the document. Pages are indexed starting at 1 (not 0!).

object_id_for_page(1)
=> 5
object_id_for_page(10)
=> 87
object_id_for_page(-11)
=> 17


126
127
128
129
130
# File 'lib/prawn/core/object_store.rb', line 126

def object_id_for_page(k)
  k -= 1 if k > 0
  flat_page_ids = get_page_objects(pages).flatten
  flat_page_ids[k]
end

#page_countObject



50
51
52
# File 'lib/prawn/core/object_store.rb', line 50

def page_count
  pages.data[:Count]
end

#pagesObject



46
47
48
# File 'lib/prawn/core/object_store.rb', line 46

def pages
  root.data[:Pages]
end

#push(*args, &block) ⇒ Object Also known as: <<

Adds the given reference to the store and returns the reference object. If the object provided is not a Prawn::Core::Reference, one is created from the arguments provided.



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/prawn/core/object_store.rb', line 58

def push(*args, &block)
  reference = if args.first.is_a?(Prawn::Core::Reference)
    args.first
  else
    Prawn::Core::Reference.new(*args, &block)
  end

  @objects[reference.identifier] = reference
  @identifiers << reference.identifier
  reference
end

#ref(data, &block) ⇒ Object



34
35
36
# File 'lib/prawn/core/object_store.rb', line 34

def ref(data, &block)
  push(size + 1, data, &block)
end

#rootObject



42
43
44
# File 'lib/prawn/core/object_store.rb', line 42

def root
  @objects[@root]
end

#sizeObject Also known as: length



82
83
84
# File 'lib/prawn/core/object_store.rb', line 82

def size
  @identifiers.size
end