pdf-reader 2.9.2 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
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"