pdfrb 0.7.24 → 0.7.25

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7f4bfdd940c5efb31509b47b458c221611bd9fab8e65f45c3c5f0d4a55af63e
4
- data.tar.gz: ca8423b413d1c1c22387df07f0cb8deac73549b3be0b944cfbe96600b43a146c
3
+ metadata.gz: 1eb0494d4b1e603ab1e6fad59bb5daa3d3ad1df02dcd57ed6b2f2445655b72d2
4
+ data.tar.gz: 3e6aae264376ab5f3027d89500d883bea9fe95a39fadc2bd01cc0f83b4914c45
5
5
  SHA512:
6
- metadata.gz: e047623b3eb1d875605e7582e56c11c38c963acef221ac017f977e9c875efc291081c2fe7f66d8ed27b1bbe5f76cf75770f8605288c89a98157d90102b2c3f9c
7
- data.tar.gz: a072c1ca23b1e030a276f8dc15483ef26d852b5889bd8896d1b6f22efcaab0e2a772c132fa14405a99d301649e4447e9dcf28133279ea592a1f297f115a4caad
6
+ metadata.gz: 7db4a10fc882da2a6b1eea1a84bff7868ffac59345ba5c7596fec36bb31fd519b8c08594f6c68362ee12802c88e1ebce20ad4fef9cfba162e686d1e393e5f3d4
7
+ data.tar.gz: 7491b71494824241e04c771bfc4a229d9e4b33ddcdbd4a49b99faa260f8866a6d08eef391f1947b93a207b72312e103d9809e8b2eac45a0a063f3d1e5f8314d1
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Cos
6
+ # Shared Arlington TSV binding for COS container classes.
7
+ # Cos::Dictionary extends this and merges field definitions via
8
+ # define_field; Model::PdfArray extends it and keeps the
9
+ # positional definition for element-type lookup. Either way the
10
+ # class is registered in Pdfrb::Model::Type.arlington_registry
11
+ # so field-link resolution can find it.
12
+ module ArlingtonBacked
13
+ # Pull the named Arlington TSV. Idempotent. Silently no-ops
14
+ # when the Arlington layer or the TSV is unavailable, so
15
+ # hand-coded subclasses still work.
16
+ def arlington_object(name, version: "latest")
17
+ return if arlington_loaded_for?(name)
18
+ return unless arlington_available?
19
+
20
+ definition = Pdfrb::Arlington::Loader.object_definition(name, version: version)
21
+ return unless definition
22
+
23
+ arlington_mark_loaded(name)
24
+ Pdfrb::Model::Type.register_arlington(name, self) if Pdfrb::Model.const_defined?(:Type)
25
+ apply_arlington_definition(definition)
26
+ end
27
+
28
+ def arlington_loaded_for?(arlington_name)
29
+ @arlington_loaded_name == arlington_name
30
+ end
31
+ private :arlington_loaded_for?
32
+
33
+ def arlington_mark_loaded(name)
34
+ @arlington_loaded_name = name
35
+ end
36
+ private :arlington_mark_loaded
37
+
38
+ def arlington_available?
39
+ Pdfrb.const_defined?(:Arlington) &&
40
+ Pdfrb::Arlington.const_defined?(:Loader)
41
+ rescue StandardError
42
+ false
43
+ end
44
+ private :arlington_available?
45
+
46
+ # Hook: containers override to consume the definition.
47
+ def apply_arlington_definition(_definition); end
48
+ private :apply_arlington_definition
49
+ end
50
+ end
51
+ end
52
+ end
@@ -13,6 +13,8 @@ module Pdfrb
13
13
  # via Pdfrb::Arlington::Loader. Calls `define_field` under
14
14
  # the hood with types translated to Ruby classes.
15
15
  class Dictionary < Pdfrb::Model::Object
16
+ extend ArlingtonBacked
17
+
16
18
  # ---- Per-class field registry ----
17
19
 
18
20
  # Shared type registry (s7.7 /Type symbol -> Dictionary
@@ -69,50 +71,20 @@ module Pdfrb
69
71
  own_fields.each { |n, f| yield n, f }
70
72
  end
71
73
 
72
- # Pull field metadata from the named Arlington TSV. Idempotent.
73
- # Silently no-ops when the Arlington layer or the TSV is
74
- # unavailable, so hand-coded subclasses still work.
75
- #
76
- # Also registers +self+ in Pdfrb::Model::Type.arlington_registry
77
- # under +name+ so field-link resolution can find this class
78
- # when other Types reference it.
79
- def arlington_object(name, version: "latest")
80
- return if arlington_loaded_for?(name)
81
- return unless arlington_available?
82
-
83
- definition = Pdfrb::Arlington::Loader.object_definition(name, version: version)
84
- return unless definition
85
-
86
- arlington_mark_loaded(name)
87
- Pdfrb::Model::Type.register_arlington(name, self) if Pdfrb::Model.const_defined?(:Type)
74
+ # Merge the TSV's field definitions into the class's field
75
+ # set (ArlingtonBacked#arlington_object hook).
76
+ def apply_arlington_definition(definition)
88
77
  definition.each_field do |field_def|
89
78
  define_field_from_arlington(field_def)
90
79
  end
91
80
  end
81
+ private :apply_arlington_definition
92
82
 
93
83
  def own_fields
94
84
  @own_fields ||= {}
95
85
  end
96
86
  private :own_fields
97
87
 
98
- def arlington_loaded_for?(arlington_name)
99
- @arlington_loaded_name == arlington_name
100
- end
101
- private :arlington_loaded_for?
102
-
103
- def arlington_mark_loaded(name)
104
- @arlington_loaded_name = name
105
- end
106
- private :arlington_mark_loaded
107
-
108
- def arlington_available?
109
- Pdfrb.const_defined?(:Arlington) &&
110
- Pdfrb::Arlington.const_defined?(:Loader)
111
- rescue StandardError
112
- false
113
- end
114
- private :arlington_available?
115
-
116
88
  # Merge Arlington field metadata with any hand-coded
117
89
  # define_field declaration. Hand-coded fields win: if the
118
90
  # class already declares this key explicitly (with a type),
@@ -15,6 +15,7 @@ module Pdfrb
15
15
  autoload :StringEncoding, "pdfrb/model/cos/string_encoding"
16
16
  autoload :Dictionary, "pdfrb/model/cos/dictionary"
17
17
  autoload :Stream, "pdfrb/model/cos/stream"
18
+ autoload :ArlingtonBacked, "pdfrb/model/cos/arlington_backed"
18
19
  end
19
20
  end
20
21
  end
@@ -8,6 +8,26 @@ module Pdfrb
8
8
  # when nested inside a typed Dictionary (field-driven).
9
9
  class PdfArray < Pdfrb::Model::Object
10
10
  include Enumerable
11
+ extend Cos::ArlingtonBacked
12
+
13
+ class << self
14
+ # ArlingtonBacked hook: array TSVs describe positional element
15
+ # types (keys "0", "1", ...), so keep the definition whole
16
+ # rather than merging per-field metadata.
17
+ def apply_arlington_definition(definition)
18
+ @arlington_definition = definition
19
+ end
20
+ private :apply_arlington_definition
21
+
22
+ def arlington_definition
23
+ @arlington_definition
24
+ end
25
+
26
+ # FieldDefinition for the element at +index+, per the TSV.
27
+ def element_field(index)
28
+ arlington_definition&.field_for(index.to_s)
29
+ end
30
+ end
11
31
 
12
32
  def initialize(arr = [], oid: 0, gen: 0, document: nil)
13
33
  super(Array(arr), oid: oid, gen: gen, document: document)
@@ -6,6 +6,7 @@ module Pdfrb
6
6
  # Crypt Filter (s7.6.5). Per-stream cipher filter spec — names
7
7
  # the cipher and authentication event.
8
8
  class CryptFilter < Pdfrb::Model::Cos::Dictionary
9
+ arlington_object "CryptFilter"
9
10
  def cipher_method; self[:CFM]&.to_sym; end
10
11
  def auth_event; self[:AuthEvent]&.to_sym; end
11
12
  def length; self[:Length]; end
@@ -27,6 +28,7 @@ module Pdfrb
27
28
  # Crypt Filter Map (s7.6.5, Table 26). Maps per-page crypt filter
28
29
  # names to the default CryptFilter used.
29
30
  class CryptFilterMap < Pdfrb::Model::Cos::Dictionary
31
+ arlington_object "CryptFilterMap"
30
32
  def filter_for(stream_name)
31
33
  value[stream_name.to_sym] || value[stream_name.to_s]
32
34
  end
@@ -41,6 +43,7 @@ module Pdfrb
41
43
  # Crypt Filter Public Key (s7.6.5, Table 26). Public-key analog
42
44
  # of CryptFilter.
43
45
  class CryptFilterPublicKey < Pdfrb::Model::Cos::Dictionary
46
+ arlington_object "CryptFilterPublicKey"
44
47
  def cipher_method; self[:CFM]&.to_sym; end
45
48
  def auth_event; self[:AuthEvent]&.to_sym; end
46
49
  def recipients; self[:Recipients]; end
@@ -49,6 +52,7 @@ module Pdfrb
49
52
  # Crypt Filter Public Key Map (s7.6.5, Table 26). Maps per-page
50
53
  # public-key crypt filters.
51
54
  class CryptFilterPublicKeyMap < Pdfrb::Model::Cos::Dictionary
55
+ arlington_object "CryptFilterPublicKeyMap"
52
56
  def filter_for(stream_name)
53
57
  value[stream_name.to_sym] || value[stream_name.to_s]
54
58
  end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfrb
4
+ module Model
5
+ module Type
6
+ # Explicit destination array [page, display_type, *params]
7
+ # (s12.3.2.2). Element 0 is a page reference (or integer page
8
+ # number); element 1 names the display mode.
9
+ class Destination < Pdfrb::Model::PdfArray
10
+ def page_ref; self[0]; end
11
+ def display_type; self[1]; end
12
+
13
+ # True when element 0 is an integer page number (GoTo D form).
14
+ def page_number?
15
+ page_ref.is_a?(Integer)
16
+ end
17
+
18
+ def page_number
19
+ page_ref if page_number?
20
+ end
21
+
22
+ def xyz?; display_type == :XYZ; end
23
+ def fit?; display_type == :Fit; end
24
+ def fit_h?; display_type == :FitH; end
25
+ def fit_v?; display_type == :FitV; end
26
+ def fit_r?; display_type == :FitR; end
27
+ def fit_b?; display_type == :FitB; end
28
+ def fit_bh?; display_type == :FitBH; end
29
+ def fit_bv?; display_type == :FitBV; end
30
+ end
31
+
32
+ # [page, :XYZ, left, top, zoom] — window positioned at a point
33
+ # (s12.3.2.2, Table 151).
34
+ class DestinationXYZ < Destination
35
+ arlington_object "DestXYZArray"
36
+
37
+ def left; self[2]; end
38
+ def top; self[3]; end
39
+ def zoom; self[4]; end
40
+
41
+ def retains_position?
42
+ left.nil? && top.nil?
43
+ end
44
+ end
45
+
46
+ # [page, :Fit] — whole page fits the window (s12.3.2.2).
47
+ class DestinationFit < Destination
48
+ arlington_object "Dest0Array"
49
+ end
50
+
51
+ # [page, :FitH, top] — page width fits the window (s12.3.2.2).
52
+ class DestinationFitH < Destination
53
+ arlington_object "Dest1Array"
54
+
55
+ def top; self[2]; end
56
+ end
57
+
58
+ # [page, :FitR, left, bottom, right, top] — rectangle fits the
59
+ # window (s12.3.2.2).
60
+ class DestinationFitR < Destination
61
+ arlington_object "Dest4Array"
62
+
63
+ def left; self[2]; end
64
+ def bottom; self[3]; end
65
+ def right; self[4]; end
66
+ def top; self[5]; end
67
+ end
68
+
69
+ # Structure-destination variants (s7.9.4, PDF 1.3+ tagging).
70
+ # Element 0 may be a structure element reference (string) instead
71
+ # of a page — used by GoToE /D chains with structure content.
72
+ class DestinationXYZStruct < DestinationXYZ
73
+ arlington_object "DestXYZStructArray"
74
+
75
+ def struct_ref?; page_ref.is_a?(String); end
76
+ end
77
+
78
+ class DestinationFitStruct < DestinationFit
79
+ arlington_object "Dest0StructArray"
80
+
81
+ def struct_ref?; page_ref.is_a?(String); end
82
+ end
83
+
84
+ class DestinationFitHStruct < DestinationFitH
85
+ arlington_object "Dest1StructArray"
86
+
87
+ def struct_ref?; page_ref.is_a?(String); end
88
+ end
89
+
90
+ class DestinationFitRStruct < DestinationFitR
91
+ arlington_object "Dest4StructArray"
92
+
93
+ def struct_ref?; page_ref.is_a?(String); end
94
+ end
95
+
96
+ # Destination dictionary (s12.3.2.3). Wraps a destination in
97
+ # target-dictionary chains (GoToE /D). /SD is the structure
98
+ # destination form.
99
+ class DestinationDict < Pdfrb::Model::Cos::Dictionary
100
+ arlington_object "DestDict"
101
+
102
+ def d; self[:D]; end
103
+ def sd; self[:SD]; end
104
+
105
+ def structure_destination?
106
+ !sd.nil?
107
+ end
108
+ end
109
+
110
+ # /Dests dictionary (s7.7.4, deprecated 2.0). Name → destination
111
+ # map living on the (page or) catalog.
112
+ class DestsMap < Pdfrb::Model::Cos::Dictionary
113
+ arlington_object "DestsMap"
114
+
115
+ def [](name)
116
+ value[name.to_sym] || value[name.to_s]
117
+ end
118
+
119
+ def add(name, destination)
120
+ value[name.to_sym] = destination
121
+ name.to_sym
122
+ end
123
+
124
+ def each_destination(&)
125
+ return enum_for(:each_destination) unless block_given?
126
+
127
+ value.each(&)
128
+ end
129
+
130
+ def names
131
+ value.keys
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -311,6 +311,19 @@ module Pdfrb
311
311
  autoload :OutputIntentsContainer, "pdfrb/model/type/misc_helpers"
312
312
  autoload :CMapStream, "pdfrb/model/type/misc_helpers"
313
313
 
314
+ # Explicit destination arrays + maps (s12.3.2).
315
+ autoload :Destination, "pdfrb/model/type/destination"
316
+ autoload :DestinationXYZ, "pdfrb/model/type/destination"
317
+ autoload :DestinationFit, "pdfrb/model/type/destination"
318
+ autoload :DestinationFitH, "pdfrb/model/type/destination"
319
+ autoload :DestinationFitR, "pdfrb/model/type/destination"
320
+ autoload :DestinationXYZStruct, "pdfrb/model/type/destination"
321
+ autoload :DestinationFitStruct, "pdfrb/model/type/destination"
322
+ autoload :DestinationFitHStruct, "pdfrb/model/type/destination"
323
+ autoload :DestinationFitRStruct, "pdfrb/model/type/destination"
324
+ autoload :DestinationDict, "pdfrb/model/type/destination"
325
+ autoload :DestsMap, "pdfrb/model/type/destination"
326
+
314
327
  # Crypt filter (s7.6.5).
315
328
  autoload :CryptFilter, "pdfrb/model/type/crypt_filter"
316
329
  autoload :CryptFilterMap, "pdfrb/model/type/crypt_filter"
data/lib/pdfrb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pdfrb
4
- VERSION = "0.7.24"
4
+ VERSION = "0.7.25"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdfrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.24
4
+ version: 0.7.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-19 00:00:00.000000000 Z
11
+ date: 2026-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -941,6 +941,7 @@ files:
941
941
  - lib/pdfrb/linearization/writer.rb
942
942
  - lib/pdfrb/model.rb
943
943
  - lib/pdfrb/model/cos.rb
944
+ - lib/pdfrb/model/cos/arlington_backed.rb
944
945
  - lib/pdfrb/model/cos/dictionary.rb
945
946
  - lib/pdfrb/model/cos/fields.rb
946
947
  - lib/pdfrb/model/cos/name_encoding.rb
@@ -1017,6 +1018,7 @@ files:
1017
1018
  - lib/pdfrb/model/type/collection_subitem.rb
1018
1019
  - lib/pdfrb/model/type/crypt_filter.rb
1019
1020
  - lib/pdfrb/model/type/d_part.rb
1021
+ - lib/pdfrb/model/type/destination.rb
1020
1022
  - lib/pdfrb/model/type/device_n.rb
1021
1023
  - lib/pdfrb/model/type/device_n_mixing_hints.rb
1022
1024
  - lib/pdfrb/model/type/device_n_process.rb