Module: Pdfrb::Task::RegenerateAppearances
- Defined in:
- lib/pdfrb/task/regenerate_appearances.rb
Overview
Walks every widget annotation in the document and regenerates the /AP /N appearance stream via Appearance::Generator. Use after mutating field values directly (e.g. via Form#set_value) or to repair documents with /NeedAppearances set so viewers don't have to synthesise appearances on the fly.
Per ISO 32000-2 ยง12.5.5, an annotation's /AP /N is the normal appearance; PDF/A requires it for every widget. This task also clears /NeedAppearances on /AcroForm since by definition all fields now have a computed appearance.
Class Method Summary collapse
-
.call(document, only: nil) ⇒ Integer
Count of appearances regenerated.
- .clear_need_appearances(document) ⇒ Object
- .each_widget(document) ⇒ Object
- .matching?(widget, only) ⇒ Boolean
- .regenerate(generator, widget) ⇒ Object
Class Method Details
.call(document, only: nil) ⇒ Integer
Returns count of appearances regenerated.
22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/pdfrb/task/regenerate_appearances.rb', line 22 def call(document, only: nil) generator = Pdfrb::Appearance::Generator.new(document) = (document).to_a count = 0 .each do || next unless matching?(, only) regenerated = regenerate(generator, ) count += 1 if regenerated end clear_need_appearances(document) count end |
.clear_need_appearances(document) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/pdfrb/task/regenerate_appearances.rb', line 83 def clear_need_appearances(document) catalog = document.catalog return unless catalog acroform = catalog.value[:AcroForm] return unless acroform if acroform.is_a?(Pdfrb::Model::Cos::Dictionary) acroform.value.delete(:NeedAppearances) elsif acroform.is_a?(::Hash) acroform.delete(:NeedAppearances) end end |
.each_widget(document) ⇒ Object
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/pdfrb/task/regenerate_appearances.rb', line 36 def (document) return enum_for(:each_widget, document) unless block_given? document.each_indirect_object do |obj| next unless obj.value.is_a?(::Hash) subtype = obj.value[:Subtype] yield obj if subtype == :Widget end end |
.matching?(widget, only) ⇒ Boolean
47 48 49 50 51 52 |
# File 'lib/pdfrb/task/regenerate_appearances.rb', line 47 def matching?(, only) return true if only.nil? ft = .value[:FT] ft && only.include?(ft.to_sym) end |
.regenerate(generator, widget) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/pdfrb/task/regenerate_appearances.rb', line 54 def regenerate(generator, ) ft = .value[:FT]&.to_sym value = .value[:V] case ft when :Tx generator.text_field(, value: value.to_s) true when :Btn if value.is_a?(::Hash) # Multi-state radio; regenerate each state's appearance. value.each_key do |state| generator.checkbox(, checked: state != :Off) end else generator.checkbox(, checked: [:Yes, true].include?(value)) end true when :Ch generator.combo(, value: value.to_s) true else false end rescue StandardError # Appearance generation is best-effort; if a single field # raises, skip it rather than aborting the whole sweep. false end |