Class: Idml::Render::PdfrbWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/idml/render/pdfrb_writer.rb

Overview

Thin adapter wrapping Pdfrb::Document for IDML→PDF rendering. Delegates all PDF assembly to pdfrb (no hand-rolled PDF code). The adapter provides a consistent interface for the Pipeline (add_page → returns Canvas, add_image → name, register_font → name, set_info, add_bookmark, subset_fonts!) while letting pdfrb handle xref, trailer, object streams, and operator emission.

Constant Summary collapse

DEFAULT_WIDTH =
612
DEFAULT_HEIGHT =
792
META_SETTERS =
{
  Title: :title=,
  Author: :author=,
  Subject: :subject=,
  Keywords: :keywords=,
  Creator: :creator=,
  Producer: :producer=,
  CreationDate: :creationdate=,
  ModDate: :moddate=,
}.freeze
COMPRESSED_OPTIONS =

Lossless writer options applied to the underlying pdfrb Document. Each entry maps a pdfrb config key to its value. Compression (FlateDecode), XRef streams, and object-stream packing are all lossless and produce smaller PDFs without throwing away any data — no image downsampling, no font information loss.

Compression is opt-in because enabling it makes stream-level assertions in specs harder (strings move into compressed ObjStms). Set compress: true on the writer or pipeline to enable.

{
  "writer.compress_streams" => true,
  "writer.compress_min_size" => 64,
  "writer.use_xref_stream" => true,
  "writer.pack_object_streams" => true,
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(compress: false) ⇒ PdfrbWriter



44
45
46
47
48
# File 'lib/idml/render/pdfrb_writer.rb', line 44

def initialize(compress: false)
  config = compress ? COMPRESSED_OPTIONS : {}
  @document = Pdfrb::Document.new(config: config)
  @image_cache = {}
end

Instance Method Details

#add_bookmark(title, page_index) ⇒ Object



64
65
66
67
# File 'lib/idml/render/pdfrb_writer.rb', line 64

def add_bookmark(title, page_index)
  page = @document.pages[page_index]
  @document.outline.add(title, dest: page)
end

#add_image(data:) ⇒ Object



56
57
58
# File 'lib/idml/render/pdfrb_writer.rb', line 56

def add_image(data:)
  @document.images.add(data)
end

#add_page(width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT) ⇒ Object



50
51
52
53
54
# File 'lib/idml/render/pdfrb_writer.rb', line 50

def add_page(width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT)
  page = @document.pages.add
  page.media_box = [0, 0, width, height]
  page.canvas
end

#add_structure_element(type, page_index:, mcid:, text: nil, alt: nil) ⇒ Object



99
100
101
102
103
# File 'lib/idml/render/pdfrb_writer.rb', line 99

def add_structure_element(type, page_index:, mcid:, text: nil, alt: nil)
  page = @document.pages[page_index]
  @document.structure.add_element(type, text: text, alt: alt,
                                        page: page, mcid: mcid)
end


105
106
107
108
109
110
111
112
113
# File 'lib/idml/render/pdfrb_writer.rb', line 105

def add_uri_link_annotation(page_index:, rect:, url:)
  page = @document.pages[page_index]
  action = @document.add({ S: :URI, URI: url },
                         type: Pdfrb::Model::Cos::Dictionary)
  action_ref = Pdfrb::Model::Reference.new(action.oid, action.gen)
  annot = @document.annotations.add(page, subtype: :Link, rect: rect)
  annot.value[:A] = action_ref
  annot
end

#build_structureObject



115
116
117
# File 'lib/idml/render/pdfrb_writer.rb', line 115

def build_structure
  @document.structure.build!
end

#documentObject



119
120
121
# File 'lib/idml/render/pdfrb_writer.rb', line 119

def document
  @document
end

#enable_taggedObject



95
96
97
# File 'lib/idml/render/pdfrb_writer.rb', line 95

def enable_tagged
  @document.structure.enable!
end

#image_name_for(uri) ⇒ Object



87
88
89
# File 'lib/idml/render/pdfrb_writer.rb', line 87

def image_name_for(uri)
  @image_cache[uri]
end

#register_font(path) ⇒ Object



60
61
62
# File 'lib/idml/render/pdfrb_writer.rb', line 60

def register_font(path)
  @document.fonts.add(File.open(path, "rb"))
end

#register_image_name(uri, name) ⇒ Object



91
92
93
# File 'lib/idml/render/pdfrb_writer.rb', line 91

def register_image_name(uri, name)
  @image_cache[uri] = name
end

#set_info(hash) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/idml/render/pdfrb_writer.rb', line 69

def set_info(hash)
  meta = @document.
  hash.each do |key, value|
    setter = META_SETTERS[key.to_sym]
    next unless setter

    meta.public_send(setter, value.to_s)
  end
end

#subset_fonts!Object



79
80
81
# File 'lib/idml/render/pdfrb_writer.rb', line 79

def subset_fonts!
  @document.fonts.subset_fonts!
end

#write(path) ⇒ Object



83
84
85
# File 'lib/idml/render/pdfrb_writer.rb', line 83

def write(path)
  @document.write(path)
end