Class: Pdfrb::Document::Annotations

Inherits:
Object
  • Object
show all
Defined in:
lib/pdfrb/document/annotations.rb

Overview

Annotations facade. Adds and enumerates annotations on pages.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document) ⇒ Annotations

Returns a new instance of Annotations.



9
10
11
# File 'lib/pdfrb/document/annotations.rb', line 9

def initialize(document)
  @document = document
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



7
8
9
# File 'lib/pdfrb/document/annotations.rb', line 7

def document
  @document
end

Instance Method Details

#add(page, subtype:, rect:, **opts) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/pdfrb/document/annotations.rb', line 13

def add(page, subtype:, rect:, **opts)
  annot = document.add(
    {
      Type: :Annot,
      Subtype: subtype,
      Rect: rect,
      P: Pdfrb::Model::Reference.new(page.oid, page.gen),
      Contents: opts[:contents],
      F: opts[:flags] || 0
    }.compact,
    type: Pdfrb::Model::Type::Annotation
  )
  annots = (page.value[:Annots] ||= [])
  annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
  annot
end

#add_free_text(page, rect:, contents:, font: nil, font_size: nil, color: nil) ⇒ Object

Free-text annotation showing inline text on the page.



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

def add_free_text(page, rect:, contents:, font: nil, font_size: nil, color: nil)
  annot = document.add(
    {
      Type: :Annot, Subtype: :FreeText, Rect: rect,
      P: Pdfrb::Model::Reference.new(page.oid, page.gen),
      Contents: contents
    },
    type: Pdfrb::Model::Type::FreeTextAnnotation
  )
  da_parts = []
  da_parts << "/#{font} #{font_size} Tf" if font && font_size
  da_parts << "#{color.join(' ')} rg" if color
  annot.value[:DA] = da_parts.join(" ") unless da_parts.empty?
  annots = (page.value[:Annots] ||= [])
  annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
  annot
end

#add_highlight(page, quad_points:, contents: nil) ⇒ Object

Highlight text-markup annotation over the given quad points.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/pdfrb/document/annotations.rb', line 73

def add_highlight(page, quad_points:, contents: nil)
  annot = document.add(
    {
      Type: :Annot, Subtype: :Highlight,
      QuadPoints: quad_points,
      P: Pdfrb::Model::Reference.new(page.oid, page.gen),
      Contents: contents
    }.compact,
    type: Pdfrb::Model::Type::HighlightAnnotation
  )
  annots = (page.value[:Annots] ||= [])
  annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
  annot
end

Hyperlink annotation pointing at a destination.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pdfrb/document/annotations.rb', line 38

def add_link(page, rect:, dest: nil, uri: nil, highlight: :Invert)
  annot = add(page, subtype: :Link, rect: rect)
  annot.value[:H] = highlight
  if dest
    annot.value[:Dest] = dest
  elsif uri
    action = document.add(
      { Type: :Action, S: :URI, URI: uri },
      type: Pdfrb::Model::Type::Action
    )
    annot.value[:A] = Pdfrb::Model::Reference.new(action.oid, action.gen)
  end
  annot
end

#add_stamp(page, rect:, name: :Draft, contents: nil) ⇒ Object

Stamp annotation (e.g. DRAFT, APPROVED, CONFIDENTIAL).



89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/pdfrb/document/annotations.rb', line 89

def add_stamp(page, rect:, name: :Draft, contents: nil)
  annot = document.add(
    {
      Type: :Annot, Subtype: :Stamp, Rect: rect, Name: name,
      P: Pdfrb::Model::Reference.new(page.oid, page.gen),
      Contents: contents
    }.compact,
    type: Pdfrb::Model::Type::StampAnnotation
  )
  annots = (page.value[:Annots] ||= [])
  annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
  annot
end

#add_text_note(page, rect:, contents:, open: false) ⇒ Object

Sticky-note / comment text annotation.



31
32
33
34
35
# File 'lib/pdfrb/document/annotations.rb', line 31

def add_text_note(page, rect:, contents:, open: false)
  annot = add(page, subtype: :Text, rect: rect, contents: contents)
  annot.value[:Open] = open unless open == false
  annot
end

#count(page) ⇒ Object



103
104
105
106
107
108
# File 'lib/pdfrb/document/annotations.rb', line 103

def count(page)
  annots = page.value[:Annots]
  return 0 unless annots

  annots.is_a?(::Array) ? annots.length : 1
end

#each(page, &block) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/pdfrb/document/annotations.rb', line 110

def each(page, &block)
  return enum_for(:each, page) unless block

  annots = page.value[:Annots]
  return self unless annots

  annots.each do |ref|
    a = ref.is_a?(Pdfrb::Model::Reference) ? document.object(ref) : ref
    yield a if a
  end
  self
end

Iterate every link annotation in the document.



138
139
140
141
142
# File 'lib/pdfrb/document/annotations.rb', line 138

def each_link(&block)
  return enum_for(:each_link) unless block

  each_of_subtype(:Link, &block)
end

#each_of_subtype(subtype, &block) ⇒ Object

Iterate annotations of a specific subtype across the whole doc.



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/pdfrb/document/annotations.rb', line 124

def each_of_subtype(subtype, &block)
  return enum_for(:each_of_subtype, subtype) unless block

  document.pages.each do |page|
    each(page) do |annot|
      next unless annot[:Subtype]&.to_sym == subtype

      yield annot
    end
  end
  self
end

#each_text_markup(&block) ⇒ Object

Iterate every text-markup annotation in the document.



152
153
154
155
156
157
158
# File 'lib/pdfrb/document/annotations.rb', line 152

def each_text_markup(&block)
  return enum_for(:each_text_markup) unless block

  %i[Highlight Underline Squiggly StrikeOut].each do |sub|
    each_of_subtype(sub, &block)
  end
end

#each_widget(&block) ⇒ Object

Iterate every widget (form) annotation in the document.



145
146
147
148
149
# File 'lib/pdfrb/document/annotations.rb', line 145

def each_widget(&block)
  return enum_for(:each_widget) unless block

  each_of_subtype(:Widget, &block)
end