pdf-reader 2.9.2 → 2.10.0

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: cc98ab07b3c66f13f663ea5faf8132b45d769912e0da737917dd054e38318ede
4
- data.tar.gz: 0f2928d9778b5b3ea8fca5e723a2b3fa6f275df70b02f1eb4385e077c535ac78
3
+ metadata.gz: 55bfae4c5211a0f3ac70845500183e237d3d5f9cc81d548a27f4b8c5fd5acfc9
4
+ data.tar.gz: 9e9000474695100c4874afd9abf5f6290ea0b59ffa773c3d03a4a3fc3d2a0a4c
5
5
  SHA512:
6
- metadata.gz: 210cd8c8cef93b0e0fac1446c091c2a62772ffe8b1786627089e5a330ca7defd501df7cccc0b48d326d38ff74318b162e512220e8a4460260bebe7da0ef8b757
7
- data.tar.gz: 047e7f6641411557b1d3b50035dbdf55647c63deede273b6ce4442230b85372045494b81e88c1ffcaa09a7c5ea26823ee33b33c3bf82013328d0e32a95021284
6
+ metadata.gz: 2dc96f064c3b233bd499a5a8140bb6f61fd1bdadb2582ac9bc569adff911e63aaadc16188d6624e0ed766481d453912bf5e0057add84262d753681cc40f51776
7
+ data.tar.gz: 64dfac4dd2b73a5302be95c47e74e7ca8b94fc6daeaea30c7a33cca6b4be79b68facc571d209f44a59de2632f6241166a290fe0f2835498b2b7d611906b05a31
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ v2.10.0 (12th May 2022)
2
+ - Various bug fixes
3
+ - Expanded sorbet type annotations
4
+
1
5
  v2.9.2 (20th February 2022)
2
6
  - Fix PDF::Reader::ObjectHash#page_references to return an Array of PDF::Reader::Reference (http://github.com/yob/pdf-reader/pull/444)
3
7
 
@@ -1,9 +1,7 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
- #
6
-
7
5
  require 'forwardable'
8
6
 
9
7
  class PDF::Reader
@@ -33,10 +31,10 @@ class PDF::Reader
33
31
  params << array.shift
34
32
 
35
33
  if params.size == 2 && params.last.is_a?(Array)
36
- widths.merge! parse_first_form(params.first, params.last)
34
+ widths.merge! parse_first_form(params.first.to_i, Array(params.last))
37
35
  params = []
38
36
  elsif params.size == 3
39
- widths.merge! parse_second_form(params[0], params[1], params[2])
37
+ widths.merge! parse_second_form(params[0].to_i, params[1].to_i, params[2].to_i)
40
38
  params = []
41
39
  end
42
40
  end
@@ -54,6 +52,8 @@ class PDF::Reader
54
52
 
55
53
  # this is the form 10 20 123 where all index between 10 and 20 have width 123
56
54
  def parse_second_form(first, final, width)
55
+ raise MalformedPDFError, "CidWidths: #{first} must be less than #{final}" unless first < final
56
+
57
57
  (first..final).inject({}) { |accum, index|
58
58
  accum[index] = width
59
59
  accum
@@ -58,10 +58,6 @@ class PDF::Reader
58
58
  def self.validate_not_nil(object, name)
59
59
  raise ArgumentError, "#{object} must not be nil" if object.nil?
60
60
  end
61
- ################################################################################
62
- def self.validate_not_nil_as_malformed(object, name)
63
- raise MalformedPDFError, "#{object} must not be nil" if object.nil?
64
- end
65
61
  end
66
62
 
67
63
  ################################################################################
@@ -125,7 +125,7 @@ class PDF::Reader
125
125
  row_data[index] = (byte + paeth) % 256
126
126
  end
127
127
  else
128
- raise ArgumentError, "Invalid filter algorithm #{filter}"
128
+ raise MalformedPDFError, "Invalid filter algorithm #{filter}"
129
129
  end
130
130
 
131
131
  s = []
@@ -205,14 +205,17 @@ class PDF::Reader
205
205
  end
206
206
 
207
207
  def extract_descendants(obj)
208
- return unless obj[:DescendantFonts]
209
208
  # per PDF 32000-1:2008 pp. 280 :DescendentFonts is:
210
209
  # A one-element array specifying the CIDFont dictionary that is the
211
210
  # descendant of this Type 0 font.
212
- descendants = @ohash.deref_array(obj[:DescendantFonts])
213
- @descendantfonts = descendants.map { |desc|
214
- PDF::Reader::Font.new(@ohash, @ohash.deref_hash(desc))
215
- }
211
+ if obj[:DescendantFonts]
212
+ descendants = @ohash.deref_array(obj[:DescendantFonts])
213
+ @descendantfonts = descendants.map { |desc|
214
+ PDF::Reader::Font.new(@ohash, @ohash.deref_hash(desc))
215
+ }
216
+ else
217
+ @descendantfonts = []
218
+ end
216
219
  end
217
220
 
218
221
  def to_utf8_via_cmap(params)
@@ -226,9 +229,7 @@ class PDF::Reader
226
229
  @tounicode.decode(c) || PDF::Reader::Encoding::UNKNOWN_CHAR
227
230
  }.flatten.pack("U*")
228
231
  when Array
229
- params.collect { |param| to_utf8_via_cmap(param) }
230
- else
231
- params
232
+ params.collect { |param| to_utf8_via_cmap(param) }.join("")
232
233
  end
233
234
  end
234
235
 
@@ -243,9 +244,7 @@ class PDF::Reader
243
244
  when String
244
245
  encoding.to_utf8(params)
245
246
  when Array
246
- params.collect { |param| to_utf8_via_encoding(param) }
247
- else
248
- params
247
+ params.collect { |param| to_utf8_via_encoding(param) }.join("")
249
248
  end
250
249
  end
251
250
 
@@ -56,7 +56,9 @@ class PDF::Reader
56
56
  end
57
57
  char_metric = ttf_program_stream.horizontal_metrics.metrics[glyph_id]
58
58
  if char_metric
59
- return char_metric.advance_width
59
+ char_metric.advance_width
60
+ else
61
+ 0
60
62
  end
61
63
  end
62
64
  end
@@ -45,7 +45,7 @@ module PDF
45
45
  def font_objects
46
46
  raw_fonts = @objects.deref_hash(fonts)
47
47
  ::Hash[raw_fonts.map { |label, font|
48
- [label, PDF::Reader::Font.new(@objects, @objects.deref_hash(font))]
48
+ [label, PDF::Reader::Font.new(@objects, @objects.deref_hash(font) || {})]
49
49
  }]
50
50
  end
51
51
 
@@ -55,6 +55,9 @@ module PDF
55
55
  # See the comments on PDF::Reader::Page#walk for more detail.
56
56
  #
57
57
  def walk(*receivers)
58
+ receivers = receivers.map { |receiver|
59
+ ValidatingReceiver.new(receiver)
60
+ }
58
61
  content_stream(receivers, raw_content)
59
62
  end
60
63
 
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
5
  module PDF
@@ -25,12 +25,14 @@ module PDF
25
25
  def initialize(data, bits_in_chunk)
26
26
  @data = data
27
27
  @data.force_encoding("BINARY")
28
- @bits_in_chunk = bits_in_chunk
28
+ set_bits_in_chunk(bits_in_chunk)
29
29
  @current_pos = 0
30
30
  @bits_left_in_byte = 8
31
31
  end
32
32
 
33
33
  def set_bits_in_chunk(bits_in_chunk)
34
+ raise MalformedPDFError, "invalid LZW bits" if bits_in_chunk < 9 || bits_in_chunk > 12
35
+
34
36
  @bits_in_chunk = bits_in_chunk
35
37
  end
36
38
 
@@ -39,7 +41,7 @@ module PDF
39
41
  chunk = -1
40
42
  while bits_left_in_chunk > 0 and @current_pos < @data.size
41
43
  chunk = 0 if chunk < 0
42
- codepoint = @data[@current_pos, 1].unpack("C*")[0]
44
+ codepoint = @data[@current_pos, 1].to_s.unpack("C*")[0].to_i
43
45
  current_byte = codepoint & (2**@bits_left_in_byte - 1) #clear consumed bits
44
46
  dif = bits_left_in_chunk - @bits_left_in_byte
45
47
  if dif > 0 then current_byte <<= dif
@@ -61,21 +63,25 @@ module PDF
61
63
  CODE_CLEAR_TABLE = 256 #clear table
62
64
 
63
65
  # stores de pairs code => string
64
- class StringTable < Hash # :nodoc:
66
+ class StringTable
65
67
  attr_reader :string_table_pos
66
68
 
67
69
  def initialize
68
- super
70
+ @data = Hash.new
69
71
  @string_table_pos = 258 #initial code
70
72
  end
71
73
 
72
74
  #if code less than 258 return fixed string
73
75
  def [](key)
74
- if key > 257 then super else key.chr end
76
+ if key > 257
77
+ @data[key]
78
+ else
79
+ key.chr
80
+ end
75
81
  end
76
82
 
77
83
  def add(string)
78
- store(@string_table_pos, string)
84
+ @data.store(@string_table_pos, string)
79
85
  @string_table_pos += 1
80
86
  end
81
87
  end
@@ -83,7 +89,7 @@ module PDF
83
89
  # Decompresses a LZW compressed string.
84
90
  #
85
91
  def self.decode(data)
86
- stream = BitStream.new data.to_s, 9 # size of codes between 9 and 12 bits
92
+ stream = BitStream.new(data.to_s, 9) # size of codes between 9 and 12 bits
87
93
  string_table = StringTable.new
88
94
  result = "".dup
89
95
  until (code = stream.read) == CODE_EOD
@@ -119,8 +125,17 @@ module PDF
119
125
  result
120
126
  end
121
127
 
122
- def self.create_new_string(string_table,some_code, other_code)
123
- string_table[some_code] + string_table[other_code][0].chr
128
+ def self.create_new_string(string_table, some_code, other_code)
129
+ raise MalformedPDFError, "invalid LZW data" if some_code.nil? || other_code.nil?
130
+
131
+ item_one = string_table[some_code]
132
+ item_two = string_table[other_code]
133
+
134
+ if item_one && item_two
135
+ item_one + item_two.chr
136
+ else
137
+ raise MalformedPDFError, "invalid LZW data"
138
+ end
124
139
  end
125
140
  private_class_method :create_new_string
126
141
 
@@ -243,7 +243,7 @@ class PDF::Reader
243
243
 
244
244
  obj.tap { |obj|
245
245
  if !obj.is_a?(PDF::Reader::Stream)
246
- raise MalformedPDFError, "expected object to be an Array or nil"
246
+ raise MalformedPDFError, "expected object to be a Stream or nil"
247
247
  end
248
248
  }
249
249
  end
@@ -496,7 +496,9 @@ class PDF::Reader
496
496
  def fetch_object_stream(key)
497
497
  if xref[key].is_a?(PDF::Reader::Reference)
498
498
  container_key = xref[key]
499
- object_streams[container_key] ||= PDF::Reader::ObjectStream.new(object(container_key))
499
+ stream = deref_stream(container_key)
500
+ raise MalformedPDFError, "Object Stream cannot be nil" if stream.nil?
501
+ object_streams[container_key] ||= PDF::Reader::ObjectStream.new(stream)
500
502
  object_streams[container_key][key.id]
501
503
  end
502
504
  end
@@ -573,7 +575,9 @@ class PDF::Reader
573
575
  def get_page_objects(obj)
574
576
  derefed_obj = deref_hash(obj)
575
577
 
576
- if derefed_obj[:Type] == :Page
578
+ if derefed_obj.nil?
579
+ raise MalformedPDFError, "Expected Page or Pages object, got nil"
580
+ elsif derefed_obj[:Type] == :Page
577
581
  [obj]
578
582
  elsif derefed_obj[:Kids]
579
583
  kids = deref_array(derefed_obj[:Kids]) || []
@@ -24,7 +24,7 @@ class PDF::Reader
24
24
  end
25
25
 
26
26
  def size
27
- @dict[:N]
27
+ TypeCheck.cast_to_int!(@dict[:N])
28
28
  end
29
29
 
30
30
  private
@@ -40,7 +40,7 @@ class PDF::Reader
40
40
  end
41
41
 
42
42
  def first
43
- @dict[:First]
43
+ TypeCheck.cast_to_int!(@dict[:First])
44
44
  end
45
45
 
46
46
  def buffer
@@ -278,7 +278,9 @@ module PDF
278
278
  []
279
279
  else
280
280
  obj = objects.deref_hash(origin)
281
- PDF::Reader::Error.validate_not_nil_as_malformed(obj, "parent")
281
+ if obj.nil?
282
+ raise MalformedPDFError, "parent mus not be nil"
283
+ end
282
284
  [ select_inheritable(obj) ] + ancestors(obj[:Parent])
283
285
  end
284
286
  end
@@ -16,7 +16,7 @@ class PDF::Reader
16
16
  :h_scaling => 1.0,
17
17
  :text_leading => 0,
18
18
  :text_font => nil,
19
- :text_font_size => nil,
19
+ :text_font_size => 0,
20
20
  :text_mode => 0,
21
21
  :text_rise => 0,
22
22
  :text_knockout => 0
@@ -32,6 +32,12 @@ class PDF::Reader
32
32
  @cs_stack = [page.color_spaces]
33
33
  @stack = [DEFAULT_GRAPHICS_STATE.dup]
34
34
  state[:ctm] = identity_matrix
35
+
36
+ # These are only valid when inside a `BT` block and we re-initialize them on each
37
+ # `BT`. However, we need the instance variables set so PDFs with the text operators
38
+ # out order don't trigger NoMethodError when these are nil
39
+ @text_matrix = identity_matrix
40
+ @text_line_matrix = identity_matrix
35
41
  end
36
42
 
37
43
  #####################################################
@@ -92,7 +92,8 @@ module PDF
92
92
  # of calling it over and over.
93
93
  #
94
94
  def xobjects
95
- @objects.deref_hash!(@resources[:XObject]) || {}
95
+ dict = @objects.deref_hash!(@resources[:XObject]) || {}
96
+ TypeCheck.cast_to_pdf_dict_with_stream_values!(dict)
96
97
  end
97
98
 
98
99
  end
@@ -40,7 +40,7 @@ class PDF::Reader
40
40
  # Creates a new stream with the specified dictionary and data. The dictionary
41
41
  # should be a standard ruby hash, the data should be a standard ruby string.
42
42
  def initialize(hash, data)
43
- @hash = hash
43
+ @hash = TypeCheck.cast_to_pdf_dict!(hash)
44
44
  @data = data
45
45
  @udata = nil
46
46
  end
@@ -9,6 +9,18 @@ module PDF
9
9
  #
10
10
  class TypeCheck
11
11
 
12
+ def self.cast_to_int!(obj)
13
+ if obj.is_a?(Integer)
14
+ obj
15
+ elsif obj.nil?
16
+ 0
17
+ elsif obj.respond_to?(:to_i)
18
+ obj.to_i
19
+ else
20
+ raise MalformedPDFError, "Unable to cast to integer"
21
+ end
22
+ end
23
+
12
24
  def self.cast_to_numeric!(obj)
13
25
  if obj.is_a?(Numeric)
14
26
  obj
@@ -46,6 +58,40 @@ module PDF
46
58
  raise MalformedPDFError, "Unable to cast to symbol"
47
59
  end
48
60
  end
61
+
62
+ def self.cast_to_symbol!(obj)
63
+ res = cast_to_symbol(obj)
64
+ if res
65
+ res
66
+ else
67
+ raise MalformedPDFError, "Unable to cast to symbol"
68
+ end
69
+ end
70
+
71
+ def self.cast_to_pdf_dict!(obj)
72
+ if obj.is_a?(Hash)
73
+ obj
74
+ elsif obj.respond_to?(:to_h)
75
+ obj.to_h
76
+ else
77
+ raise MalformedPDFError, "Unable to cast to hash"
78
+ end
79
+ end
80
+
81
+ def self.cast_to_pdf_dict_with_stream_values!(obj)
82
+ if obj.is_a?(Hash)
83
+ result = Hash.new
84
+ obj.each do |k, v|
85
+ raise MalformedPDFError, "Expected a stream" unless v.is_a?(PDF::Reader::Stream)
86
+ result[cast_to_symbol!(k)] = v
87
+ end
88
+ result
89
+ elsif obj.respond_to?(:to_h)
90
+ cast_to_pdf_dict_with_stream_values!(obj.to_h)
91
+ else
92
+ raise MalformedPDFError, "Unable to cast to hash"
93
+ end
94
+ end
49
95
  end
50
96
  end
51
97
  end
@@ -53,12 +53,13 @@ class PDF::Reader
53
53
  private
54
54
 
55
55
  def control_character?(code_point)
56
- @font.encoding.int_to_name(code_point).first.to_s[/\Acontrol..\Z/]
56
+ match = @font.encoding.int_to_name(code_point).first.to_s[/\Acontrol..\Z/]
57
+ match ? true : false
57
58
  end
58
59
 
59
60
  def extract_basefont(font_name)
60
61
  if BUILTINS.include?(font_name)
61
- font_name
62
+ font_name.to_s
62
63
  else
63
64
  "Times-Roman"
64
65
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
5
  class PDF::Reader
@@ -22,7 +22,11 @@ class PDF::Reader
22
22
 
23
23
  w = @widths[code_point]
24
24
  # 0 is a valid width
25
- return w.to_f unless w.nil?
25
+ if w
26
+ w.to_f
27
+ else
28
+ 0
29
+ end
26
30
  end
27
31
  end
28
32
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
5
  class PDF::Reader
@@ -10,8 +10,8 @@ class PDF::Reader
10
10
  def initialize(font)
11
11
  @font = font
12
12
 
13
- if @font.font_descriptor
14
- @missing_width = @font.font_descriptor.missing_width
13
+ if fd = @font.font_descriptor
14
+ @missing_width = fd.missing_width
15
15
  else
16
16
  @missing_width = 0
17
17
  end
@@ -30,25 +30,23 @@ class PDF::Reader
30
30
 
31
31
  # in ruby a negative index is valid, and will go from the end of the array
32
32
  # which is undesireable in this case.
33
- if @font.first_char && @font.first_char <= code_point
34
- @font.widths.fetch(code_point - @font.first_char, @missing_width).to_f
33
+ first_char = @font.first_char
34
+ if first_char && first_char <= code_point
35
+ @font.widths.fetch(code_point - first_char, @missing_width.to_i).to_f
35
36
  else
36
37
  @missing_width.to_f
37
38
  end
38
39
  end
39
40
 
40
41
  def glyph_width_from_descriptor(code_point)
41
- return unless @font.font_descriptor
42
-
43
42
  # true type fonts will have most of their information contained
44
43
  # with-in a program inside the font descriptor, however the widths
45
44
  # may not be in standard PDF glyph widths (1000 units => 1 text space unit)
46
45
  # so this width will need to be scaled
47
- w = @font.font_descriptor.glyph_width(code_point)
48
- if w
49
- w.to_f * @font.font_descriptor.glyph_to_pdf_scale_factor
50
- else
51
- nil
46
+ if fd = @font.font_descriptor
47
+ if w = fd.glyph_width(code_point)
48
+ w.to_f * fd.glyph_to_pdf_scale_factor.to_f
49
+ end
52
50
  end
53
51
  end
54
52
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
5
  class PDF::Reader
@@ -10,8 +10,8 @@ class PDF::Reader
10
10
  def initialize(font)
11
11
  @font = font
12
12
 
13
- if @font.font_descriptor
14
- @missing_width = @font.font_descriptor.missing_width
13
+ if fd = @font.font_descriptor
14
+ @missing_width = fd.missing_width
15
15
  else
16
16
  @missing_width = 0
17
17
  end
@@ -23,8 +23,9 @@ class PDF::Reader
23
23
 
24
24
  # in ruby a negative index is valid, and will go from the end of the array
25
25
  # which is undesireable in this case.
26
- if @font.first_char <= code_point
27
- @font.widths.fetch(code_point - @font.first_char, @missing_width).to_f
26
+ first_char = @font.first_char
27
+ if first_char && first_char <= code_point
28
+ @font.widths.fetch(code_point - first_char, @missing_width.to_i).to_f
28
29
  else
29
30
  @missing_width.to_f
30
31
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # typed: true
2
+ # typed: strict
3
3
  # frozen_string_literal: true
4
4
 
5
5
  class PDF::Reader
@@ -13,13 +13,16 @@ class PDF::Reader
13
13
 
14
14
  def initialize(font)
15
15
  @font = font
16
- @descendant_font = @font.descendantfonts.first
17
16
  end
18
17
 
19
18
  def glyph_width(code_point)
20
19
  return 0 if code_point.nil? || code_point < 0
21
20
 
22
- @descendant_font.glyph_width(code_point).to_f
21
+ if descendant_font = @font.descendantfonts.first
22
+ descendant_font.glyph_width(code_point).to_f
23
+ else
24
+ 0
25
+ end
23
26
  end
24
27
  end
25
28
  end
data/rbi/pdf-reader.rbi CHANGED
@@ -145,16 +145,18 @@ module PDF
145
145
  end
146
146
 
147
147
  class CidWidths
148
- sig { params(default: T.untyped, array: T.untyped).void }
149
- def initialize(default, array); end
148
+ sig { params(default: Numeric, array: T::Array[Numeric]).void }
149
+ def initialize(default, array)
150
+ @widths = T.let(T.unsafe(nil), T::Hash[Numeric, Numeric])
151
+ end
150
152
 
151
- sig { params(default: T.untyped, array: T.untyped).returns(T.untyped) }
153
+ sig { params(default: Numeric, array: T::Array[Numeric]).returns(T::Hash[Numeric, Numeric]) }
152
154
  def parse_array(default, array); end
153
155
 
154
- sig { params(first: T.untyped, widths: T.untyped).returns(T.untyped) }
156
+ sig { params(first: Integer, widths: T::Array[Numeric]).returns(T::Hash[Numeric, Numeric]) }
155
157
  def parse_first_form(first, widths); end
156
158
 
157
- sig { params(first: T.untyped, final: T.untyped, width: T.untyped).returns(T.untyped) }
159
+ sig { params(first: Integer, final: Integer, width: Numeric).returns(T::Hash[Numeric, Numeric]) }
158
160
  def parse_second_form(first, final, width); end
159
161
  end
160
162
 
@@ -279,9 +281,6 @@ module PDF
279
281
 
280
282
  sig { params(object: Object, name: String).void }
281
283
  def self.validate_not_nil(object, name); end
282
-
283
- sig { params(object: Object, name: String).void }
284
- def self.validate_not_nil_as_malformed(object, name); end
285
284
  end
286
285
 
287
286
  class MalformedPDFError < RuntimeError
@@ -300,138 +299,146 @@ module PDF
300
299
  end
301
300
 
302
301
  class Font
303
- sig { returns(T.untyped) }
302
+ sig { returns(T.nilable(Symbol)) }
304
303
  attr_accessor :subtype
305
304
 
306
- sig { returns(T.untyped) }
305
+ sig { returns(PDF::Reader::Encoding) }
307
306
  attr_accessor :encoding
308
307
 
309
- sig { returns(T.untyped) }
308
+ sig { returns(T::Array[PDF::Reader::Font]) }
310
309
  attr_accessor :descendantfonts
311
310
 
312
- sig { returns(T.untyped) }
311
+ sig { returns(PDF::Reader::CMap) }
313
312
  attr_accessor :tounicode
314
313
 
315
- sig { returns(T.untyped) }
314
+ sig { returns(T::Array[Integer]) }
316
315
  attr_reader :widths
317
316
 
318
- sig { returns(T.untyped) }
317
+ sig { returns(T.nilable(Integer)) }
319
318
  attr_reader :first_char
320
319
 
321
- sig { returns(T.untyped) }
320
+ sig { returns(T.nilable(Integer)) }
322
321
  attr_reader :last_char
323
322
 
324
- sig { returns(T.untyped) }
323
+ sig { returns(T.nilable(Symbol)) }
325
324
  attr_reader :basefont
326
325
 
327
- sig { returns(T.untyped) }
326
+ sig { returns(T.nilable(PDF::Reader::FontDescriptor)) }
328
327
  attr_reader :font_descriptor
329
328
 
330
- sig { returns(T.untyped) }
329
+ sig { returns(T::Array[Numeric]) }
331
330
  attr_reader :cid_widths
332
331
 
333
- sig { returns(T.untyped) }
332
+ sig { returns(Numeric) }
334
333
  attr_reader :cid_default_width
335
334
 
336
- sig { params(ohash: T.untyped, obj: T.untyped).void }
335
+ sig { params(ohash: PDF::Reader::ObjectHash, obj: T::Hash[Symbol, T.untyped]).void }
337
336
  def initialize(ohash, obj); end
338
337
 
339
- sig { params(params: T.untyped).returns(T.untyped) }
338
+ sig { params(params: T.any(Integer, String, T::Array[T.untyped])).returns(String) }
340
339
  def to_utf8(params); end
341
340
 
342
- sig { params(data: T.untyped).returns(T.untyped) }
341
+ sig { params(data: String).returns(T::Array[T.nilable(T.any(Numeric, String))]) }
343
342
  def unpack(data); end
344
343
 
345
- sig { params(code_point: T.untyped).returns(T.untyped) }
344
+ sig { params(code_point: T.any(String, Integer)).returns(T.untyped) }
346
345
  def glyph_width(code_point); end
347
346
 
348
- sig { params(font_name: T.untyped).returns(T.untyped) }
347
+ sig { params(font_name: Symbol).returns(PDF::Reader::Encoding) }
349
348
  def default_encoding(font_name); end
350
349
 
351
- sig { returns(T.untyped) }
350
+ sig {
351
+ returns(
352
+ T.any(
353
+ PDF::Reader::WidthCalculator::BuiltIn,
354
+ PDF::Reader::WidthCalculator::Composite,
355
+ PDF::Reader::WidthCalculator::TrueType,
356
+ PDF::Reader::WidthCalculator::TypeOneOrThree,
357
+ PDF::Reader::WidthCalculator::TypeZero,
358
+ )
359
+ )
360
+ }
352
361
  def build_width_calculator; end
353
362
 
354
- sig { params(obj: T.untyped).returns(T.untyped) }
363
+ sig { params(obj: T.untyped).void }
355
364
  def extract_base_info(obj); end
356
365
 
357
- sig { params(obj: T.untyped).returns(T.untyped) }
366
+ sig { params(obj: T.untyped).void }
358
367
  def extract_descriptor(obj); end
359
368
 
360
- sig { params(obj: T.untyped).returns(T.untyped) }
369
+ sig { params(obj: T.untyped).void }
361
370
  def extract_descendants(obj); end
362
371
 
363
- sig { params(params: T.untyped).returns(T.untyped) }
372
+ sig { params(params: T.any(Integer, String, T::Array[T.untyped])).returns(String) }
364
373
  def to_utf8_via_cmap(params); end
365
374
 
366
- sig { params(params: T.untyped).returns(T.untyped) }
375
+ sig { params(params: T.any(Integer, String, T::Array[T.untyped])).returns(String) }
367
376
  def to_utf8_via_encoding(params); end
368
377
  end
369
378
 
370
379
  class FontDescriptor
371
- sig { returns(T.untyped) }
380
+ sig { returns(String) }
372
381
  attr_reader :font_name
373
382
 
374
- sig { returns(T.untyped) }
383
+ sig { returns(T.nilable(String)) }
375
384
  attr_reader :font_family
376
385
 
377
- sig { returns(T.untyped) }
386
+ sig { returns(Symbol) }
378
387
  attr_reader :font_stretch
379
388
 
380
- sig { returns(T.untyped) }
389
+ sig { returns(Numeric) }
381
390
  attr_reader :font_weight
382
391
 
383
- sig { returns(T.untyped) }
392
+ sig { returns(T::Array[Numeric]) }
384
393
  attr_reader :font_bounding_box
385
394
 
386
- sig { returns(T.untyped) }
395
+ sig { returns(Numeric) }
387
396
  attr_reader :cap_height
388
397
 
389
- sig { returns(T.untyped) }
398
+ sig { returns(Numeric) }
390
399
  attr_reader :ascent
391
400
 
392
- sig { returns(T.untyped) }
401
+ sig { returns(Numeric) }
393
402
  attr_reader :descent
394
403
 
395
- sig { returns(T.untyped) }
404
+ sig { returns(Numeric) }
396
405
  attr_reader :leading
397
406
 
398
- sig { returns(T.untyped) }
407
+ sig { returns(Numeric) }
399
408
  attr_reader :avg_width
400
409
 
401
- sig { returns(T.untyped) }
410
+ sig { returns(Numeric) }
402
411
  attr_reader :max_width
403
412
 
404
- sig { returns(T.untyped) }
413
+ sig { returns(Numeric) }
405
414
  attr_reader :missing_width
406
415
 
407
- sig { returns(T.untyped) }
416
+ sig { returns(T.nilable(Numeric)) }
408
417
  attr_reader :italic_angle
409
418
 
410
- sig { returns(T.untyped) }
419
+ sig { returns(T.nilable(Numeric)) }
411
420
  attr_reader :stem_v
412
421
 
413
- sig { returns(T.untyped) }
422
+ sig { returns(T.nilable(Numeric)) }
414
423
  attr_reader :x_height
415
424
 
416
- sig { returns(T.untyped) }
425
+ sig { returns(Integer) }
417
426
  attr_reader :font_flags
418
427
 
419
428
  sig { params(ohash: PDF::Reader::ObjectHash, fd_hash: T::Hash[T.untyped, T.untyped]).void }
420
429
  def initialize(ohash, fd_hash); end
421
430
 
422
- sig { params(char_code: T.untyped).returns(T.untyped) }
431
+ sig { params(char_code: Integer).returns(Numeric) }
423
432
  def glyph_width(char_code); end
424
433
 
425
- sig { returns(T.untyped) }
434
+ sig { returns(Numeric) }
426
435
  def glyph_to_pdf_scale_factor; end
427
436
 
428
- sig { returns(T.untyped) }
437
+ sig { returns(TTFunk::File) }
429
438
  def ttf_program_stream; end
430
439
  end
431
440
 
432
441
  class FormXObject
433
- include ResourceMethods
434
-
435
442
  sig { returns(T.untyped) }
436
443
  attr_reader :xobject
437
444
 
@@ -517,34 +524,43 @@ module PDF
517
524
  CODE_CLEAR_TABLE = 256
518
525
 
519
526
  class BitStream
520
- sig { params(data: T.untyped, bits_in_chunk: T.untyped).void }
521
- def initialize(data, bits_in_chunk); end
527
+ sig { params(data: String, bits_in_chunk: Integer).void }
528
+ def initialize(data, bits_in_chunk)
529
+ @data = T.let(T.unsafe(nil), String)
530
+ @bits_in_chunk = T.let(T.unsafe(nil), Integer)
531
+ @current_pos = T.let(T.unsafe(nil), Integer)
532
+ @bits_left_in_byte = T.let(T.unsafe(nil), Integer)
533
+
534
+ end
522
535
 
523
- sig { params(bits_in_chunk: T.untyped).returns(T.untyped) }
536
+ sig { params(bits_in_chunk: Integer).void }
524
537
  def set_bits_in_chunk(bits_in_chunk); end
525
538
 
526
- sig { returns(T.untyped) }
539
+ sig { returns(Integer) }
527
540
  def read; end
528
541
  end
529
542
 
530
- class StringTable < Hash
531
- sig { returns(T.untyped) }
543
+ class StringTable
544
+ sig { returns(Integer) }
532
545
  attr_reader :string_table_pos
533
546
 
534
547
  sig { void }
535
- def initialize; end
548
+ def initialize
549
+ @data = T.let(T.unsafe(nil), T::Hash[Integer, String])
550
+ @string_table_pos = T.let(T.unsafe(nil), Integer)
551
+ end
536
552
 
537
- sig { params(key: T.untyped).returns(T.untyped) }
553
+ sig { params(key: Integer).returns(T.nilable(String)) }
538
554
  def [](key); end
539
555
 
540
- sig { params(string: T.untyped).returns(T.untyped) }
556
+ sig { params(string: String).void }
541
557
  def add(string); end
542
558
  end
543
559
 
544
- sig { params(data: T.untyped).returns(T.untyped) }
560
+ sig { params(data: String).returns(String) }
545
561
  def self.decode(data); end
546
562
 
547
- sig { params(string_table: T.untyped, some_code: T.untyped, other_code: T.untyped).returns(T.untyped) }
563
+ sig { params(string_table: PDF::Reader::LZW::StringTable, some_code: T.nilable(Integer), other_code: T.nilable(Integer)).returns(String) }
548
564
  def self.create_new_string(string_table, some_code, other_code); end
549
565
  end
550
566
 
@@ -647,7 +663,7 @@ module PDF
647
663
  sig { params(key: T.untyped).returns(T.nilable(T::Array[Numeric])) }
648
664
  def deref_array_of_numbers(key); end
649
665
 
650
- sig { params(key: T.untyped).returns(T.nilable(T:Hash[Symbol, T.untyped])) }
666
+ sig { params(key: T.untyped).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
651
667
  def deref_hash(key); end
652
668
 
653
669
  sig { params(key: T.untyped).returns(T.nilable(Symbol)) }
@@ -674,10 +690,10 @@ module PDF
674
690
  sig { params(key: T.untyped).returns(T.untyped) }
675
691
  def deref!(key); end
676
692
 
677
- sig { params(key: T.untyped).returns(T::Array[T.untyped]) }
693
+ sig { params(key: T.untyped).returns(T.nilable(T::Array[T.untyped])) }
678
694
  def deref_array!(key); end
679
695
 
680
- sig { params(key: T.untyped).returns(T::Hash[Symbol, T.untyped]) }
696
+ sig { params(key: T.untyped).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
681
697
  def deref_hash!(key); end
682
698
 
683
699
  sig { params(key: T.untyped, local_default: T.untyped).returns(T.untyped) }
@@ -763,22 +779,25 @@ module PDF
763
779
  end
764
780
 
765
781
  class ObjectStream
766
- sig { params(stream: T.untyped).void }
767
- def initialize(stream); end
782
+ sig { params(stream: PDF::Reader::Stream).void }
783
+ def initialize(stream)
784
+ @dict = T.let(T.unsafe(nil), T::Hash[Symbol, T.untyped])
785
+ @data = T.let(T.unsafe(nil), String)
786
+ end
768
787
 
769
788
  sig { params(objid: T.untyped).returns(T.untyped) }
770
789
  def [](objid); end
771
790
 
772
- sig { returns(T.untyped) }
791
+ sig { returns(Integer) }
773
792
  def size; end
774
793
 
775
- sig { returns(T.untyped) }
794
+ sig { returns(T::Hash[Integer, Integer]) }
776
795
  def offsets; end
777
796
 
778
- sig { returns(T.untyped) }
797
+ sig { returns(Integer) }
779
798
  def first; end
780
799
 
781
- sig { returns(T.untyped) }
800
+ sig { returns(PDF::Reader::Buffer) }
782
801
  def buffer; end
783
802
  end
784
803
 
@@ -807,8 +826,6 @@ module PDF
807
826
  end
808
827
 
809
828
  class Page
810
- include ResourceMethods
811
-
812
829
  sig { returns(PDF::Reader::ObjectHash) }
813
830
  attr_reader :objects
814
831
 
@@ -881,7 +898,7 @@ module PDF
881
898
  sig { params(origin: T.untyped).returns(T.untyped) }
882
899
  def ancestors(origin = @page_object[:Parent]); end
883
900
 
884
- sig { params(obj: T::Hash[T.untyped, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
901
+ sig { params(obj: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
885
902
  def select_inheritable(obj); end
886
903
  end
887
904
 
@@ -1386,31 +1403,36 @@ module PDF
1386
1403
  def series(*methods); end
1387
1404
  end
1388
1405
 
1389
- module ResourceMethods
1390
- extend T::Helpers
1406
+ class Resources
1391
1407
 
1392
- sig { returns(T.untyped) }
1408
+ sig { params(objects: PDF::Reader::ObjectHash, resources: T::Hash[T.untyped, T.untyped]).void }
1409
+ def initialize(objects, resources)
1410
+ @objects = T.let(T.unsafe(nil), PDF::Reader::ObjectHash)
1411
+ @resources = T.let(T.unsafe(nil), T::Hash[Symbol, T.untyped])
1412
+ end
1413
+
1414
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1393
1415
  def color_spaces; end
1394
1416
 
1395
- sig { returns(T::Hash[T.untyped, T.untyped]) }
1417
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1396
1418
  def fonts; end
1397
1419
 
1398
- sig { returns(T.untyped) }
1420
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1399
1421
  def graphic_states; end
1400
1422
 
1401
- sig { returns(T.untyped) }
1423
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1402
1424
  def patterns; end
1403
1425
 
1404
- sig { returns(T.untyped) }
1426
+ sig { returns(T::Array[Symbol]) }
1405
1427
  def procedure_sets; end
1406
1428
 
1407
- sig { returns(T.untyped) }
1429
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1408
1430
  def properties; end
1409
1431
 
1410
- sig { returns(T.untyped) }
1432
+ sig { returns(T::Hash[Symbol, T.untyped]) }
1411
1433
  def shadings; end
1412
1434
 
1413
- sig { returns(T.untyped) }
1435
+ sig { returns(T::Hash[Symbol, PDF::Reader::Stream]) }
1414
1436
  def xobjects; end
1415
1437
  end
1416
1438
 
@@ -1674,6 +1696,9 @@ module PDF
1674
1696
 
1675
1697
  class TypeCheck
1676
1698
 
1699
+ sig { params(obj: T.untyped).returns(Integer) }
1700
+ def self.cast_to_int!(obj); end
1701
+
1677
1702
  sig { params(obj: T.untyped).returns(Numeric) }
1678
1703
  def self.cast_to_numeric!(obj); end
1679
1704
 
@@ -1682,6 +1707,15 @@ module PDF
1682
1707
 
1683
1708
  sig { params(obj: T.untyped).returns(T.nilable(Symbol)) }
1684
1709
  def self.cast_to_symbol(obj); end
1710
+
1711
+ sig { params(obj: T.untyped).returns(Symbol) }
1712
+ def self.cast_to_symbol!(obj); end
1713
+
1714
+ sig { params(obj: T.untyped).returns(T::Hash[Symbol, T.untyped]) }
1715
+ def self.cast_to_pdf_dict!(obj); end
1716
+
1717
+ sig { params(obj: T.untyped).returns(T::Hash[Symbol, PDF::Reader::Stream]) }
1718
+ def self.cast_to_pdf_dict_with_stream_values!(obj); end
1685
1719
  end
1686
1720
 
1687
1721
  class ValidatingReceiver
@@ -1923,54 +1957,67 @@ module PDF
1923
1957
  :ZapfDingbats
1924
1958
  ]
1925
1959
 
1926
- sig { params(font: T.untyped).void }
1927
- def initialize(font); end
1960
+ sig { params(font: PDF::Reader::Font).void }
1961
+ def initialize(font)
1962
+ @font = T.let(T.unsafe(nil), PDF::Reader::Font)
1963
+ end
1928
1964
 
1929
- sig { params(code_point: T.untyped).returns(T.untyped) }
1965
+ sig { params(code_point: T.nilable(Integer)).returns(Numeric) }
1930
1966
  def glyph_width(code_point); end
1931
1967
 
1932
- sig { params(code_point: T.untyped).returns(T.untyped) }
1968
+ sig { params(code_point: Integer).returns(T::Boolean) }
1933
1969
  def control_character?(code_point); end
1934
1970
 
1935
- sig { params(font_name: T.untyped).returns(T.untyped) }
1971
+ sig { params(font_name: T.nilable(Symbol)).returns(String) }
1936
1972
  def extract_basefont(font_name); end
1937
1973
  end
1938
1974
 
1939
1975
  class Composite
1940
- sig { params(font: T.untyped).void }
1941
- def initialize(font); end
1976
+ sig { params(font: PDF::Reader::Font).void }
1977
+ def initialize(font)
1978
+ @font = T.let(T.unsafe(nil), PDF::Reader::Font)
1979
+ @widths = T.let(T.unsafe(nil), PDF::Reader::CidWidths)
1980
+ end
1942
1981
 
1943
- sig { params(code_point: T.untyped).returns(T.untyped) }
1982
+ sig { params(code_point: T.nilable(Integer)).returns(Numeric) }
1944
1983
  def glyph_width(code_point); end
1945
1984
  end
1946
1985
 
1947
1986
  class TrueType
1948
- sig { params(font: T.untyped).void }
1949
- def initialize(font); end
1987
+ sig { params(font: PDF::Reader::Font).void }
1988
+ def initialize(font)
1989
+ @font = T.let(T.unsafe(nil), PDF::Reader::Font)
1990
+ @missing_width = T.let(T.unsafe(nil), Numeric)
1991
+ end
1950
1992
 
1951
- sig { params(code_point: T.untyped).returns(T.untyped) }
1993
+ sig { params(code_point: T.nilable(Integer)).returns(Numeric) }
1952
1994
  def glyph_width(code_point); end
1953
1995
 
1954
- sig { params(code_point: T.untyped).returns(T.untyped) }
1996
+ sig { params(code_point: Integer).returns(T.nilable(Numeric)) }
1955
1997
  def glyph_width_from_font(code_point); end
1956
1998
 
1957
- sig { params(code_point: T.untyped).returns(T.untyped) }
1999
+ sig { params(code_point: Integer).returns(T.nilable(Numeric)) }
1958
2000
  def glyph_width_from_descriptor(code_point); end
1959
2001
  end
1960
2002
 
1961
2003
  class TypeOneOrThree
1962
- sig { params(font: T.untyped).void }
1963
- def initialize(font); end
2004
+ sig { params(font: PDF::Reader::Font).void }
2005
+ def initialize(font)
2006
+ @font = T.let(T.unsafe(nil), PDF::Reader::Font)
2007
+ @missing_width = T.let(T.unsafe(nil), Numeric)
2008
+ end
1964
2009
 
1965
- sig { params(code_point: T.untyped).returns(T.untyped) }
2010
+ sig { params(code_point: T.nilable(Integer)).returns(Numeric) }
1966
2011
  def glyph_width(code_point); end
1967
2012
  end
1968
2013
 
1969
2014
  class TypeZero
1970
- sig { params(font: T.untyped).void }
1971
- def initialize(font); end
2015
+ sig { params(font: PDF::Reader::Font).void }
2016
+ def initialize(font)
2017
+ @font = T.let(T.unsafe(nil), PDF::Reader::Font)
2018
+ end
1972
2019
 
1973
- sig { params(code_point: T.untyped).returns(T.untyped) }
2020
+ sig { params(code_point: T.nilable(Integer)).returns(Numeric) }
1974
2021
  def glyph_width(code_point); end
1975
2022
  end
1976
2023
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdf-reader
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.2
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Healy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-20 00:00:00.000000000 Z
11
+ date: 2022-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -288,9 +288,9 @@ licenses:
288
288
  - MIT
289
289
  metadata:
290
290
  bug_tracker_uri: https://github.com/yob/pdf-reader/issues
291
- changelog_uri: https://github.com/yob/pdf-reader/blob/v2.9.2/CHANGELOG
292
- documentation_uri: https://www.rubydoc.info/gems/pdf-reader/2.9.2
293
- source_code_uri: https://github.com/yob/pdf-reader/tree/v2.9.2
291
+ changelog_uri: https://github.com/yob/pdf-reader/blob/v2.10.0/CHANGELOG
292
+ documentation_uri: https://www.rubydoc.info/gems/pdf-reader/2.10.0
293
+ source_code_uri: https://github.com/yob/pdf-reader/tree/v2.10.0
294
294
  post_install_message:
295
295
  rdoc_options:
296
296
  - "--title"