pdfrb 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pdfrb/annotation/base.rb +2 -2
  3. data/lib/pdfrb/appearance/generator.rb +1 -1
  4. data/lib/pdfrb/cli/images.rb +1 -1
  5. data/lib/pdfrb/cli.rb +3 -3
  6. data/lib/pdfrb/color/default_profile.rb +1 -1
  7. data/lib/pdfrb/compare/comparator.rb +2 -4
  8. data/lib/pdfrb/conformance/ltv.rb +1 -1
  9. data/lib/pdfrb/conformance/pades.rb +4 -4
  10. data/lib/pdfrb/conformance/pdf_2_af.rb +2 -2
  11. data/lib/pdfrb/conformance/pdf_a.rb +10 -20
  12. data/lib/pdfrb/conformance/pdf_x.rb +6 -16
  13. data/lib/pdfrb/conformance/tagged_pdf.rb +1 -1
  14. data/lib/pdfrb/content/canvas.rb +25 -33
  15. data/lib/pdfrb/content/hidden_text_detector.rb +2 -3
  16. data/lib/pdfrb/content/shading/base.rb +1 -1
  17. data/lib/pdfrb/content/tiling_pattern.rb +1 -1
  18. data/lib/pdfrb/digital_signature/signing.rb +2 -2
  19. data/lib/pdfrb/document/annotations.rb +10 -10
  20. data/lib/pdfrb/document/associated_files.rb +2 -2
  21. data/lib/pdfrb/document/colors.rb +1 -1
  22. data/lib/pdfrb/document/destinations.rb +4 -4
  23. data/lib/pdfrb/document/encryption.rb +1 -1
  24. data/lib/pdfrb/document/files.rb +5 -5
  25. data/lib/pdfrb/document/fonts/subsetting.rb +87 -0
  26. data/lib/pdfrb/document/fonts.rb +10 -80
  27. data/lib/pdfrb/document/form.rb +9 -9
  28. data/lib/pdfrb/document/form_xobject.rb +1 -1
  29. data/lib/pdfrb/document/graphics_state.rb +1 -1
  30. data/lib/pdfrb/document/images.rb +1 -6
  31. data/lib/pdfrb/document/info.rb +1 -1
  32. data/lib/pdfrb/document/layers.rb +1 -1
  33. data/lib/pdfrb/document/metadata.rb +1 -1
  34. data/lib/pdfrb/document/outline.rb +8 -8
  35. data/lib/pdfrb/document/output_intents.rb +3 -3
  36. data/lib/pdfrb/document/pages.rb +19 -8
  37. data/lib/pdfrb/document/pdf_a.rb +1 -1
  38. data/lib/pdfrb/document/portfolio.rb +3 -3
  39. data/lib/pdfrb/document/shadings.rb +2 -9
  40. data/lib/pdfrb/document/stamps.rb +2 -2
  41. data/lib/pdfrb/document/structure.rb +9 -9
  42. data/lib/pdfrb/document.rb +19 -2
  43. data/lib/pdfrb/encryption/security_handler.rb +1 -2
  44. data/lib/pdfrb/font/cff/subsetter.rb +0 -0
  45. data/lib/pdfrb/font/sfnt.rb +73 -0
  46. data/lib/pdfrb/font/true_type/subsetter.rb +1 -57
  47. data/lib/pdfrb/font/true_type/wrapper.rb +3 -3
  48. data/lib/pdfrb/font.rb +1 -0
  49. data/lib/pdfrb/font_loader/true_type.rb +2 -2
  50. data/lib/pdfrb/font_loader/type3.rb +1 -1
  51. data/lib/pdfrb/importer.rb +3 -3
  52. data/lib/pdfrb/linearization/writer.rb +1 -1
  53. data/lib/pdfrb/model/object.rb +7 -0
  54. data/lib/pdfrb/model/type/action_hide.rb +1 -1
  55. data/lib/pdfrb/model/type/action_sound.rb +2 -2
  56. data/lib/pdfrb/model/type/add_action_catalog.rb +1 -1
  57. data/lib/pdfrb/model/type/add_action_form_field.rb +1 -1
  58. data/lib/pdfrb/model/type/add_action_page_object.rb +1 -1
  59. data/lib/pdfrb/model/type/add_action_screen_annotation.rb +1 -1
  60. data/lib/pdfrb/model/type/add_action_widget_annotation.rb +1 -1
  61. data/lib/pdfrb/model/type/alternate_image.rb +2 -2
  62. data/lib/pdfrb/model/type/bead.rb +4 -4
  63. data/lib/pdfrb/model/type/catalog.rb +1 -1
  64. data/lib/pdfrb/model/type/d_part.rb +4 -4
  65. data/lib/pdfrb/model/type/document_security_store.rb +1 -1
  66. data/lib/pdfrb/model/type/dss.rb +1 -1
  67. data/lib/pdfrb/model/type/function_stitching.rb +1 -1
  68. data/lib/pdfrb/model/type/generic_appearance.rb +1 -1
  69. data/lib/pdfrb/model/type/opt_content_ext.rb +2 -2
  70. data/lib/pdfrb/model/type/optional_content_membership.rb +2 -2
  71. data/lib/pdfrb/model/type/page.rb +5 -7
  72. data/lib/pdfrb/model/type/page_tree_node.rb +2 -2
  73. data/lib/pdfrb/model/type/rich_media_configuration.rb +1 -1
  74. data/lib/pdfrb/model/type/struct_elem.rb +2 -2
  75. data/lib/pdfrb/model/type/struct_tree_root.rb +2 -2
  76. data/lib/pdfrb/model/type/thread.rb +3 -3
  77. data/lib/pdfrb/model/type/three_d_stream.rb +1 -1
  78. data/lib/pdfrb/model/type/viewport.rb +1 -1
  79. data/lib/pdfrb/model/type/vri.rb +1 -1
  80. data/lib/pdfrb/model/type/web_capture_command.rb +1 -1
  81. data/lib/pdfrb/model/type/web_capture_image_set.rb +1 -1
  82. data/lib/pdfrb/model/type/web_capture_page_set.rb +2 -2
  83. data/lib/pdfrb/pdf_version.rb +23 -0
  84. data/lib/pdfrb/task/extract_images.rb +1 -2
  85. data/lib/pdfrb/task/extract_text.rb +1 -1
  86. data/lib/pdfrb/task/merge.rb +3 -3
  87. data/lib/pdfrb/task/optimize.rb +2 -6
  88. data/lib/pdfrb/task/thumbnail.rb +1 -1
  89. data/lib/pdfrb/version.rb +1 -1
  90. data/lib/pdfrb/writer.rb +7 -15
  91. data/lib/pdfrb/xmp.rb +2 -2
  92. data/lib/pdfrb.rb +1 -0
  93. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6ed6487322f48831706d1efa10d78b12bbb0965d8c46232b8d333130fe63e91
4
- data.tar.gz: f3da7f40c6b4f1e53b454d70eaac66a2fd42d3f73c03802dc01a9bdffbdd3915
3
+ metadata.gz: 84368b352e856470e7d3f3374071df7724c21d5dba77596842ac5bacc419db59
4
+ data.tar.gz: c0bfb8c0a8803aa74ecf43d1e3e35ff18b17bc457582705c409d8fae89b8f50f
5
5
  SHA512:
6
- metadata.gz: 922050302dd2668bdf08e8fcfb612a02e99e0b8a90c0ce667f2910398a5cbece4fd656b1d2cf615c4e410d368534f31a0071afac6e80b5b81982f65c7b78b9a3
7
- data.tar.gz: f80c263e29e5b17659e7e9eeef9dbedac5865ffbb38d9871e9687bbbe1cc8ad7a1743c0c9dd9dbb18eb9fcb072c0c9032391983df129b04eb9b15f0d148a1abd
6
+ metadata.gz: 4d6aec972d3b32bc66f70098ab1122472fef43c675d4eaba1b77cb4c3b74231a515f9ad877d648c8b28d3dc874b55475327b20ade2b2dcc85d70e3e15712fdbc
7
+ data.tar.gz: 65fd26f6e44e1bcaa18471e86662f53e46ae4c2ac9a91a82fb182adbb10c7ef6616e6ab5505379dbc42c414a6684f848864648c486567a59e2f9aa695de67f57
@@ -39,7 +39,7 @@ module Pdfrb
39
39
  Type: :Annot,
40
40
  Subtype: subtype,
41
41
  Rect: rect,
42
- P: Pdfrb::Model::Reference.new(page.oid, page.gen),
42
+ P: page.ref,
43
43
  Contents: contents,
44
44
  F: flags,
45
45
  }.compact
@@ -64,7 +64,7 @@ module Pdfrb
64
64
 
65
65
  def attach_to_page(page, annot)
66
66
  annots = page.value[:Annots]
67
- ref = Pdfrb::Model::Reference.new(annot.oid, annot.gen)
67
+ ref = annot.ref
68
68
  if annots.nil?
69
69
  page.value[:Annots] = [ref]
70
70
  elsif annots.is_a?(::Array)
@@ -195,7 +195,7 @@ module Pdfrb
195
195
 
196
196
  def set_appearance(field, form, state_name = :Normal)
197
197
  form_stream = form.stream
198
- ref = Pdfrb::Model::Reference.new(form_stream.oid, form_stream.gen)
198
+ ref = form_stream.ref
199
199
 
200
200
  ap = field.value[:AP]
201
201
  if ap.nil?
@@ -18,7 +18,7 @@ module Pdfrb
18
18
 
19
19
  xo = xo.value if xo.is_a?(Pdfrb::Model::Cos::Dictionary)
20
20
  xo&.each do |name, ref|
21
- obj = ref.is_a?(Pdfrb::Model::Reference) ? doc.object(ref) : ref
21
+ obj = doc.resolve(ref)
22
22
  next unless obj&.value&.[](:Subtype) == :Image
23
23
 
24
24
  count += 1
data/lib/pdfrb/cli.rb CHANGED
@@ -158,7 +158,7 @@ module Pdfrb
158
158
  return unless fields
159
159
 
160
160
  fields.each do |ref|
161
- field = ref.is_a?(Pdfrb::Model::Reference) ? doc.object(ref) : ref
161
+ field = doc.resolve(ref)
162
162
  next unless field
163
163
 
164
164
  name = field[:T] || "(unnamed)"
@@ -330,7 +330,7 @@ module Pdfrb
330
330
  O: o_entry, U: u_entry },
331
331
  type: Pdfrb::Model::Cos::Dictionary
332
332
  )
333
- doc.trailer[:Encrypt] = Pdfrb::Model::Reference.new(encrypt_dict.oid, encrypt_dict.gen)
333
+ doc.trailer[:Encrypt] = encrypt_dict.ref
334
334
 
335
335
  # Set up the handler so Writer can encrypt per-object.
336
336
  handler = Pdfrb::Encryption::StandardSecurityHandler.new(
@@ -364,7 +364,7 @@ module Pdfrb
364
364
  O: o_entry, U: u_entry, OE: "".b, UE: "".b },
365
365
  type: Pdfrb::Model::Cos::Dictionary
366
366
  )
367
- doc.trailer[:Encrypt] = Pdfrb::Model::Reference.new(encrypt_dict.oid, encrypt_dict.gen)
367
+ doc.trailer[:Encrypt] = encrypt_dict.ref
368
368
  doc.config["encryption.password"] = user_pw
369
369
  end
370
370
 
@@ -47,7 +47,7 @@ module Pdfrb
47
47
  type: Pdfrb::Model::Cos::Stream
48
48
  )
49
49
  stream.stream = bytes
50
- [:ICCBased, Pdfrb::Model::Reference.new(stream.oid, stream.gen)]
50
+ [:ICCBased, stream.ref]
51
51
  end
52
52
 
53
53
  # ---- Header construction ----
@@ -96,8 +96,7 @@ module Pdfrb
96
96
 
97
97
  def inventory_fonts(doc)
98
98
  fonts = Set.new
99
- doc.each_indirect_object do |obj|
100
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
99
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
101
100
  next unless obj[:Type] == :Font
102
101
 
103
102
  name = obj[:BaseFont] || obj[:Name] || "Unknown"
@@ -117,8 +116,7 @@ module Pdfrb
117
116
 
118
117
  def count_images(doc)
119
118
  count = 0
120
- doc.each_indirect_object do |obj|
121
- next unless obj.is_a?(Pdfrb::Model::Cos::Stream)
119
+ doc.each_indirect_of(Pdfrb::Model::Cos::Stream) do |obj|
122
120
  next unless obj[:Subtype] == :Image
123
121
 
124
122
  count += 1
@@ -87,7 +87,7 @@ module Pdfrb
87
87
  fields = Pdfrb::Conformance::Pades.signature_fields(doc)
88
88
  has_archival = fields.any? do |field|
89
89
  v = field[:V]
90
- v_obj = v.is_a?(Pdfrb::Model::Reference) ? doc.object(v) : v
90
+ v_obj = doc.resolve(v)
91
91
  v_obj && v_obj[:Type]&.to_sym == :DocTimeStamp
92
92
  end
93
93
  next nil if has_archival
@@ -52,7 +52,7 @@ module Pdfrb
52
52
  v = field[:V]
53
53
  next unless v
54
54
 
55
- v_obj = v.is_a?(Pdfrb::Model::Reference) ? doc.object(v) : v
55
+ v_obj = doc.resolve(v)
56
56
  next if v_obj && ALLOWED_SIGNATURE_TYPES.include?(v_obj[:Type]&.to_sym)
57
57
 
58
58
  vs << Violation.new(
@@ -81,7 +81,7 @@ module Pdfrb
81
81
  v = field[:V]
82
82
  next unless v
83
83
 
84
- v_obj = v.is_a?(Pdfrb::Model::Reference) ? doc.object(v) : v
84
+ v_obj = doc.resolve(v)
85
85
  has_timestamp = v_obj && (
86
86
  v_obj[:Type]&.to_sym == :DocTimeStamp ||
87
87
  (v_obj[:ByteRange] && timestamp_in_signature?(v_obj))
@@ -134,7 +134,7 @@ module Pdfrb
134
134
  # protecting the DSS.
135
135
  has_archival = signature_fields(doc).any? do |field|
136
136
  v = field[:V]
137
- v_obj = v.is_a?(Pdfrb::Model::Reference) ? doc.object(v) : v
137
+ v_obj = doc.resolve(v)
138
138
  v_obj && v_obj[:Type]&.to_sym == :DocTimeStamp
139
139
  end
140
140
  next nil if has_archival
@@ -173,7 +173,7 @@ module Pdfrb
173
173
  return [] unless fields.is_a?(::Array)
174
174
 
175
175
  fields.filter_map do |ref|
176
- obj = ref.is_a?(Pdfrb::Model::Reference) ? document.object(ref) : ref
176
+ obj = document.resolve(ref)
177
177
  next nil unless obj
178
178
 
179
179
  obj[:FT]&.to_sym == :Sig ? obj : nil
@@ -131,7 +131,7 @@ module Pdfrb
131
131
  af_value = af.is_a?(Pdfrb::Model::PdfArray) ? af.value : af
132
132
  entries = af_value.is_a?(::Array) ? af_value : [af_value]
133
133
  entries.each do |e|
134
- resolved = e.is_a?(Pdfrb::Model::Reference) ? document.object(e) : e
134
+ resolved = document.resolve(e)
135
135
  yield container, resolved if resolved
136
136
  end
137
137
  end
@@ -153,7 +153,7 @@ module Pdfrb
153
153
  af_value = af.is_a?(Pdfrb::Model::PdfArray) ? af.value : af
154
154
  entries = af_value.is_a?(::Array) ? af_value : [af_value]
155
155
  entries.each do |e|
156
- resolved = e.is_a?(Pdfrb::Model::Reference) ? document.object(e) : e
156
+ resolved = document.resolve(e)
157
157
  next unless resolved && resolved.value[:Type] == :FileSpec
158
158
 
159
159
  yield container, resolved
@@ -31,8 +31,7 @@ module Pdfrb
31
31
  id: "6.1-4", description: "JavaScript prohibited",
32
32
  severity: :error, spec_clause: "ISO 19005-1 6.1",
33
33
  check: ->(doc) {
34
- doc.each_indirect_object do |obj|
35
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
34
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
36
35
  if obj.value[:S] == :JavaScript
37
36
  return Violation.new(rule_id: "6.1-4", message: "PDF/A prohibits JavaScript actions",
38
37
  object: "JavaScript action", severity: :error,
@@ -65,7 +64,7 @@ module Pdfrb
65
64
  next unless fonts
66
65
 
67
66
  fonts.each_value do |ref|
68
- f = ref.is_a?(Pdfrb::Model::Reference) ? doc.object(ref) : ref
67
+ f = doc.resolve(ref)
69
68
  next unless f
70
69
  next if f[:FontDescriptor]
71
70
 
@@ -201,8 +200,7 @@ module Pdfrb
201
200
  id: "a1-1", description: "JPEG2000 not allowed in A-1",
202
201
  severity: :error, spec_clause: "ISO 19005-1 6.2.4",
203
202
  check: ->(doc) {
204
- doc.each_indirect_object do |obj|
205
- next unless obj.is_a?(Pdfrb::Model::Cos::Stream)
203
+ doc.each_indirect_of(Pdfrb::Model::Cos::Stream) do |obj|
206
204
  next unless obj[:Filter] == :JPXDecode
207
205
 
208
206
  return Violation.new(rule_id: "a1-1",
@@ -217,8 +215,7 @@ module Pdfrb
217
215
  id: "a1-2", description: "Object streams not allowed in A-1",
218
216
  severity: :error, spec_clause: "ISO 19005-1 6.2.4",
219
217
  check: ->(doc) {
220
- doc.each_indirect_object do |obj|
221
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
218
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
222
219
  next unless obj.value[:Type] == :ObjStm
223
220
 
224
221
  return Violation.new(rule_id: "a1-2",
@@ -247,9 +244,7 @@ module Pdfrb
247
244
  id: "a1-4", description: "LZWDecode not allowed in A-1",
248
245
  severity: :error, spec_clause: "ISO 19005-1 6.2.4",
249
246
  check: ->(doc) {
250
- doc.each_indirect_object do |obj|
251
- next unless obj.is_a?(Pdfrb::Model::Cos::Stream)
252
-
247
+ doc.each_indirect_of(Pdfrb::Model::Cos::Stream) do |obj|
253
248
  f = obj[:Filter]
254
249
  fs = f.is_a?(::Array) ? f : [f]
255
250
  next unless fs.include?(:LZWDecode)
@@ -269,8 +264,7 @@ module Pdfrb
269
264
  id: "a2-1", description: "PostScript XObjects prohibited",
270
265
  severity: :warning, spec_clause: "ISO 19005-2 6.2.4",
271
266
  check: ->(doc) {
272
- doc.each_indirect_object do |obj|
273
- next unless obj.is_a?(Pdfrb::Model::Cos::Stream)
267
+ doc.each_indirect_of(Pdfrb::Model::Cos::Stream) do |obj|
274
268
  next unless [:PS, :PSXObject].include?(obj[:Subtype])
275
269
 
276
270
  return Violation.new(rule_id: "a2-1",
@@ -285,8 +279,7 @@ module Pdfrb
285
279
  id: "a2-2", description: "Embedded files not allowed in A-2",
286
280
  severity: :error, spec_clause: "ISO 19005-2 6.2",
287
281
  check: ->(doc) {
288
- doc.each_indirect_object do |obj|
289
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
282
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
290
283
  next unless obj.value[:Type] == :EmbeddedFile
291
284
 
292
285
  return Violation.new(rule_id: "a2-2",
@@ -316,8 +309,7 @@ module Pdfrb
316
309
  severity: :error, spec_clause: "ISO 19005-3 6.2",
317
310
  check: ->(doc) {
318
311
  vs = []
319
- doc.each_indirect_object do |obj|
320
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
312
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
321
313
  next unless obj.value[:Type] == :Filespec
322
314
  next if obj.value[:AFRelationship]
323
315
 
@@ -348,8 +340,7 @@ module Pdfrb
348
340
  severity: :error, spec_clause: "ISO 19005-4 6.2",
349
341
  check: ->(doc) {
350
342
  vs = []
351
- doc.each_indirect_object do |obj|
352
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
343
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
353
344
  next unless obj.value[:Type] == :Filespec
354
345
  next if obj.value[:AFRelationship]
355
346
 
@@ -366,8 +357,7 @@ module Pdfrb
366
357
  severity: :error, spec_clause: "ISO 19005-4 6.2.3",
367
358
  check: ->(doc) {
368
359
  vs = []
369
- doc.each_indirect_object do |annot|
370
- next unless annot.is_a?(Pdfrb::Model::Cos::Dictionary)
360
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |annot|
371
361
  next unless annot.value[:Type] == :Annot
372
362
 
373
363
  st = annot.value[:Subtype]
@@ -94,7 +94,7 @@ module Pdfrb
94
94
 
95
95
  fonts_hash = fonts.is_a?(Pdfrb::Model::Cos::Dictionary) ? fonts.value : fonts
96
96
  fonts_hash&.each_value do |ref|
97
- font = ref.is_a?(Pdfrb::Model::Reference) ? doc.object(ref) : ref
97
+ font = doc.resolve(ref)
98
98
  next unless font
99
99
 
100
100
  fd = font[:FontDescriptor]
@@ -150,9 +150,7 @@ module Pdfrb
150
150
  spec_clause: "ISO 15930 §6.5",
151
151
  check: ->(doc) {
152
152
  violations = []
153
- doc.each_indirect_object do |obj|
154
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
155
-
153
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
156
154
  s = obj[:S]
157
155
  next unless [:JavaScript, :JS, :Launch, :URI].include?(s)
158
156
 
@@ -174,7 +172,7 @@ module Pdfrb
174
172
 
175
173
  intents = [intents] unless intents.is_a?(::Array)
176
174
  intents.any? do |ref|
177
- obj = ref.is_a?(Pdfrb::Model::Reference) ? doc.object(ref) : ref
175
+ obj = doc.resolve(ref)
178
176
  obj && obj.value[:S] == :GTS_PDFX
179
177
  end
180
178
  end
@@ -231,7 +229,7 @@ module Pdfrb
231
229
  spec_clause: "ISO 15930-11 6.1",
232
230
  check: ->(doc) {
233
231
  v = doc.version.to_s
234
- next nil if compare_versions(v, "2.0") >= 0
232
+ next nil if Pdfrb::PdfVersion.compare(v, "2.0") >= 0
235
233
 
236
234
  Violation.new(
237
235
  rule_id: "x6-1",
@@ -257,7 +255,7 @@ module Pdfrb
257
255
  else [intents]
258
256
  end
259
257
  has_pdfx = intents_array.any? do |i|
260
- obj = i.is_a?(Pdfrb::Model::Reference) ? doc.object(i) : i
258
+ obj = doc.resolve(i)
261
259
  obj && obj[:S] == :GTS_PDFX
262
260
  end
263
261
  next nil if has_pdfx
@@ -280,16 +278,8 @@ module Pdfrb
280
278
  rs.register(X6_OUTPUT_INTENT_RULE)
281
279
  end
282
280
 
283
- def compare_versions(a, b)
284
- aa = a.to_s.split(".").map(&:to_i)
285
- bb = b.to_s.split(".").map(&:to_i)
286
- (aa <=> bb) || 0
287
- end
288
-
289
281
  def scan_color_spaces(doc, &block)
290
- doc.each_indirect_object do |obj|
291
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
292
-
282
+ doc.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
293
283
  cs = obj.value[:ColorSpace]
294
284
  next unless cs
295
285
 
@@ -145,7 +145,7 @@ module Pdfrb
145
145
  root_ref = document.catalog[:StructTreeRoot]
146
146
  return unless root_ref
147
147
 
148
- root = root_ref.is_a?(Pdfrb::Model::Reference) ? document.object(root_ref) : root_ref
148
+ root = document.resolve(root_ref)
149
149
  return unless root
150
150
 
151
151
  first_kids = structure_kids(root, document)
@@ -43,13 +43,11 @@ module Pdfrb
43
43
  end
44
44
 
45
45
  def concat(a, b, c, d, e, f, &)
46
- emit_op Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f
47
- return self unless block_given?
46
+ return emit_op(Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f) unless block_given?
48
47
 
49
- begin
48
+ save_graphics_state do
49
+ emit_op(Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f)
50
50
  yield self
51
- ensure
52
- emit_op Pdfrb::Content::Operator::SaveGraphicsState
53
51
  end
54
52
  self
55
53
  end
@@ -282,41 +280,28 @@ module Pdfrb
282
280
  create_ext_g_state(BM: mode.to_s))
283
281
  end
284
282
 
285
- def with_transparency(opacity: 1.0, blend_mode: nil)
286
- save_graphics_state
287
- self.opacity = opacity if opacity < 1.0
288
- self.blend_mode = blend_mode if blend_mode
289
-
290
- begin
283
+ def with_transparency(opacity: 1.0, blend_mode: nil, &)
284
+ save_graphics_state do
285
+ self.opacity = opacity if opacity < 1.0
286
+ self.blend_mode = blend_mode if blend_mode
291
287
  yield self
292
- ensure
293
- emit_op(Pdfrb::Content::Operator::RestoreGraphicsState)
294
288
  end
295
289
  self
296
290
  end
297
291
 
298
292
  def draw_image(name, at: nil, width: nil, height: nil, matrix: nil)
299
- @used_xobjects[name] = true
300
- save_graphics_state do
301
- if matrix
302
- a, b, c, d, e, f = matrix
303
- concat(a, b, c, d, e, f)
304
- emit_op(Pdfrb::Content::Operator::InvokeXObject, name)
305
- else
306
- translate(at[0], at[1])
307
- concat(width, 0, 0, height, 0, 0)
308
- append(" /#{name} Do\n")
309
- end
293
+ if matrix
294
+ a, b, c, d, e, f = matrix
295
+ invoke_xobject(name, matrix: [a, b, c, d, e, f])
296
+ else
297
+ invoke_xobject(name, matrix: [width, 0, 0, height, 0, 0],
298
+ pre_translate: at)
310
299
  end
311
300
  self
312
301
  end
313
302
 
314
303
  def draw_image_matrix(name, a:, b:, c:, d:, e:, f:)
315
- @used_xobjects[name] = true
316
- save_graphics_state do
317
- concat(a, b, c, d, e, f)
318
- emit_op(Pdfrb::Content::Operator::InvokeXObject, name)
319
- end
304
+ invoke_xobject(name, matrix: [a, b, c, d, e, f])
320
305
  self
321
306
  end
322
307
 
@@ -327,13 +312,20 @@ module Pdfrb
327
312
  # @param at [Array<Numeric>] x, y translation.
328
313
  # @param matrix [Array<Numeric>, nil] 6-element transform matrix.
329
314
  def draw_form_xobject(name, at: [0, 0], matrix: nil)
315
+ translate = matrix.nil? ? at : nil
316
+ invoke_xobject(name, matrix: matrix, pre_translate: translate)
317
+ self
318
+ end
319
+
320
+ # Invoke an XObject (/Do) inside a saved graphics state, applying
321
+ # an optional translation then a 6-element transform matrix.
322
+ def invoke_xobject(name, matrix: nil, pre_translate: nil)
330
323
  @used_xobjects[name] = true
331
324
  save_graphics_state do
325
+ translate(pre_translate[0], pre_translate[1]) if pre_translate
332
326
  if matrix
333
327
  a, b, c, d, e, f = matrix
334
- concat(a, b, c, d, e, f)
335
- elsif at
336
- translate(at[0], at[1])
328
+ emit_op(Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f)
337
329
  end
338
330
  emit_op(Pdfrb::Content::Operator::InvokeXObject, name)
339
331
  end
@@ -531,7 +523,7 @@ module Pdfrb
531
523
  )
532
524
  r = @stream.value[:Resources] || {}
533
525
  eg = r[:ExtGState] || {}
534
- eg[name] = Pdfrb::Model::Reference.new(gs.oid, gs.gen)
526
+ eg[name] = gs.ref
535
527
  r[:ExtGState] = eg
536
528
  @stream.value[:Resources] = r
537
529
  name
@@ -55,8 +55,7 @@ module Pdfrb
55
55
  end
56
56
 
57
57
  def find_page(stream_obj)
58
- @document.each_indirect_object do |obj|
59
- next unless obj.is_a?(Pdfrb::Model::Cos::Dictionary)
58
+ @document.each_indirect_of(Pdfrb::Model::Cos::Dictionary) do |obj|
60
59
  next unless obj[:Type] == :Page
61
60
 
62
61
  contents = obj[:Contents]
@@ -69,7 +68,7 @@ module Pdfrb
69
68
  end
70
69
 
71
70
  return obj if list.any? do |c|
72
- c_obj = c.is_a?(Pdfrb::Model::Reference) ? @document.object(c) : c
71
+ c_obj = @document.resolve(c)
73
72
  c_obj == stream_obj
74
73
  end
75
74
  end
@@ -31,7 +31,7 @@ module Pdfrb
31
31
  # @return [Symbol] resource name (e.g. :Sh1)
32
32
  def register_on(document, page)
33
33
  shading_obj = document.add(to_dict, type: Pdfrb::Model::Cos::Dictionary)
34
- ref = Pdfrb::Model::Reference.new(shading_obj.oid, shading_obj.gen)
34
+ ref = shading_obj.ref
35
35
  resources = ensure_resources(document, page)
36
36
  shading_dict = resources.value[:Shading]
37
37
  if shading_dict.nil?
@@ -51,7 +51,7 @@ module Pdfrb
51
51
  yield canvas
52
52
  end
53
53
 
54
- ref = Pdfrb::Model::Reference.new(pattern_stream.oid, pattern_stream.gen)
54
+ ref = pattern_stream.ref
55
55
  register_in_resources(document, page, ref)
56
56
  end
57
57
 
@@ -43,12 +43,12 @@ module Pdfrb
43
43
 
44
44
  field = document.add(
45
45
  { Type: :Annot, Subtype: :Widget, FT: :Sig, T: "Signature1",
46
- V: Pdfrb::Model::Reference.new(sig_dict.oid, sig_dict.gen),
46
+ V: sig_dict.ref,
47
47
  Rect: [0, 0, 0, 0] },
48
48
  type: Pdfrb::Model::Cos::Dictionary
49
49
  )
50
50
  catalog.value[:AcroForm][:Fields] <<
51
- Pdfrb::Model::Reference.new(field.oid, field.gen)
51
+ field.ref
52
52
  end
53
53
 
54
54
  def serialize(document)
@@ -16,14 +16,14 @@ module Pdfrb
16
16
  Type: :Annot,
17
17
  Subtype: subtype,
18
18
  Rect: rect,
19
- P: Pdfrb::Model::Reference.new(page.oid, page.gen),
19
+ P: page.ref,
20
20
  Contents: opts[:contents],
21
21
  F: opts[:flags] || 0
22
22
  }.compact,
23
23
  type: Pdfrb::Model::Type::Annotation
24
24
  )
25
25
  annots = (page.value[:Annots] ||= [])
26
- annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
26
+ annots << annot.ref
27
27
  annot
28
28
  end
29
29
 
@@ -45,7 +45,7 @@ module Pdfrb
45
45
  { Type: :Action, S: :URI, URI: uri },
46
46
  type: Pdfrb::Model::Type::Action
47
47
  )
48
- annot.value[:A] = Pdfrb::Model::Reference.new(action.oid, action.gen)
48
+ annot.value[:A] = action.ref
49
49
  end
50
50
  annot
51
51
  end
@@ -55,7 +55,7 @@ module Pdfrb
55
55
  annot = document.add(
56
56
  {
57
57
  Type: :Annot, Subtype: :FreeText, Rect: rect,
58
- P: Pdfrb::Model::Reference.new(page.oid, page.gen),
58
+ P: page.ref,
59
59
  Contents: contents
60
60
  },
61
61
  type: Pdfrb::Model::Type::FreeTextAnnotation
@@ -65,7 +65,7 @@ module Pdfrb
65
65
  da_parts << "#{color.join(' ')} rg" if color
66
66
  annot.value[:DA] = da_parts.join(" ") unless da_parts.empty?
67
67
  annots = (page.value[:Annots] ||= [])
68
- annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
68
+ annots << annot.ref
69
69
  annot
70
70
  end
71
71
 
@@ -75,13 +75,13 @@ module Pdfrb
75
75
  {
76
76
  Type: :Annot, Subtype: :Highlight,
77
77
  QuadPoints: quad_points,
78
- P: Pdfrb::Model::Reference.new(page.oid, page.gen),
78
+ P: page.ref,
79
79
  Contents: contents
80
80
  }.compact,
81
81
  type: Pdfrb::Model::Type::HighlightAnnotation
82
82
  )
83
83
  annots = (page.value[:Annots] ||= [])
84
- annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
84
+ annots << annot.ref
85
85
  annot
86
86
  end
87
87
 
@@ -90,13 +90,13 @@ module Pdfrb
90
90
  annot = document.add(
91
91
  {
92
92
  Type: :Annot, Subtype: :Stamp, Rect: rect, Name: name,
93
- P: Pdfrb::Model::Reference.new(page.oid, page.gen),
93
+ P: page.ref,
94
94
  Contents: contents
95
95
  }.compact,
96
96
  type: Pdfrb::Model::Type::StampAnnotation
97
97
  )
98
98
  annots = (page.value[:Annots] ||= [])
99
- annots << Pdfrb::Model::Reference.new(annot.oid, annot.gen)
99
+ annots << annot.ref
100
100
  annot
101
101
  end
102
102
 
@@ -114,7 +114,7 @@ module Pdfrb
114
114
  return self unless annots
115
115
 
116
116
  annots.each do |ref|
117
- a = ref.is_a?(Pdfrb::Model::Reference) ? document.object(ref) : ref
117
+ a = document.resolve(ref)
118
118
  yield a if a
119
119
  end
120
120
  self
@@ -54,7 +54,7 @@ module Pdfrb
54
54
  filespec = document.files.add(data, name: filename,
55
55
  description: description,
56
56
  mime_type: mime_type)
57
- ref = Pdfrb::Model::Reference.new(filespec.oid, filespec.gen)
57
+ ref = filespec.ref
58
58
  filespec.value[:AFRelationship] = relationship
59
59
  add_to_catalog(ref, relationship: relationship)
60
60
  ref
@@ -95,7 +95,7 @@ module Pdfrb
95
95
 
96
96
  refs = af.is_a?(::Array) ? af : [af]
97
97
  refs.filter_map do |ref|
98
- obj = ref.is_a?(Pdfrb::Model::Reference) ? document.object(ref) : ref
98
+ obj = document.resolve(ref)
99
99
  obj if obj.is_a?(Pdfrb::Model::Cos::Dictionary)
100
100
  end
101
101
  end
@@ -30,7 +30,7 @@ module Pdfrb
30
30
  stream.stream = profile.raw_data
31
31
  Pdfrb::Model::PdfArray.new([
32
32
  :ICCBased,
33
- Pdfrb::Model::Reference.new(stream.oid, stream.gen),
33
+ stream.ref,
34
34
  ])
35
35
  end
36
36
 
@@ -79,7 +79,7 @@ module Pdfrb
79
79
  d = catalog.value[:Dests]
80
80
  return nil unless d
81
81
 
82
- d.is_a?(Pdfrb::Model::Reference) ? document.object(d) : d
82
+ document.resolve(d)
83
83
  end
84
84
 
85
85
  def resolved_name_tree
@@ -93,7 +93,7 @@ module Pdfrb
93
93
  d = names.is_a?(Pdfrb::Model::Cos::Dictionary) ? names.value[:Dests] : names[:Dests]
94
94
  return nil unless d
95
95
 
96
- d.is_a?(Pdfrb::Model::Reference) ? document.object(d) : d
96
+ document.resolve(d)
97
97
  end
98
98
 
99
99
  def lookup_in_name_tree(node, name)
@@ -107,7 +107,7 @@ module Pdfrb
107
107
  arr = node.value[:Kids]
108
108
  arr = arr.to_a if arr.is_a?(Pdfrb::Model::PdfArray)
109
109
  arr.each do |kid_ref|
110
- kid = kid_ref.is_a?(Pdfrb::Model::Reference) ? document.object(kid_ref) : kid_ref
110
+ kid = document.resolve(kid_ref)
111
111
  result = lookup_in_name_tree(kid, name)
112
112
  return result if result
113
113
  end
@@ -130,7 +130,7 @@ module Pdfrb
130
130
  arr = node.value[:Kids]
131
131
  arr = arr.to_a if arr.is_a?(Pdfrb::Model::PdfArray)
132
132
  arr.each do |kid_ref|
133
- kid = kid_ref.is_a?(Pdfrb::Model::Reference) ? document.object(kid_ref) : kid_ref
133
+ kid = document.resolve(kid_ref)
134
134
  each_name_tree_key(kid, &block)
135
135
  end
136
136
  elsif node.is_a?(Hash) && node[:Names]