Class: Acrofill::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/acrofill/writer.rb

Overview

Writes the document back out as a fresh PDF: only objects reachable from the trailer are emitted, renumbered contiguously, with a classic xref table. Existing streams are copied verbatim with their original filters.

Constant Summary collapse

HEADER =
"%PDF-1.6\n%\xE2\xE3\xCF\xD3\n".b

Instance Method Summary collapse

Constructor Details

#initialize(document) ⇒ Writer

Returns a new instance of Writer.



12
13
14
# File 'lib/acrofill/writer.rb', line 12

def initialize(document)
  @doc = document
end

Instance Method Details

#renderObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/acrofill/writer.rb', line 16

def render
  order = reachable_oids
  oid_map = order.each_with_index.to_h { |oid, idx| [oid, idx + 1] }
  serializer = Serializer.new(oid_map)

  out = HEADER.dup
  offsets = []
  order.each do |oid|
    offsets << out.bytesize
    out << "#{oid_map[oid]} 0 obj\n"
    out << serialize_object(@doc.objects[oid], serializer)
    out << "\nendobj\n"
  end

  xref_offset = out.bytesize
  out << "xref\n0 #{order.size + 1}\n0000000000 65535 f \n"
  offsets.each { |offset| out << format("%010d 00000 n \n", offset) }

  trailer = {
    Size: order.size + 1,
    Root: @doc.trailer[:Root],
    Info: @doc.trailer[:Info],
    ID: trailer_id(out)
  }.compact
  out << "trailer\n#{serializer.serialize(trailer)}\n"
  out << "startxref\n#{xref_offset}\n%%EOF\n"
  out
end