hexapdf 0.12.2 → 0.12.3

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: d95e6e2abba7581aab78e449bf860c3955170d4c266850373296300495236c44
4
- data.tar.gz: '0950af72d8864e98a70367ee28bdf09bc09aa83cace38933aa613bc8d476263d'
3
+ metadata.gz: 889b4bf1bc77da0a3fdfc62d2b5b09042aa1b5a567d5ed80ae382e6cdeb193f9
4
+ data.tar.gz: 67f217de3dbd01653e9df4e8f8af7e8dba3745cd772e6d6ab930411ff3d1cfb3
5
5
  SHA512:
6
- metadata.gz: c3c4ad1073d3ea9b820dc129348cf2d571159ea129aa65a10546552ae52e19cf29d74a4716e3fcefac10b34f9d2ad7e833bb90355c81564a152c853e0a406ea4
7
- data.tar.gz: 637e17817d1aa8eb3b75035aa5d654f5bdbd7b531fb16776da49945c5100ab0705ab7d59b300f192b865d75ded43edae48d2f15541c2a93edbdedba9318f896a
6
+ metadata.gz: 71affdceb736e0645c45b181a585b3a425135c0b22fba1daf28d89aaa6e73e5226f18a1e420fb75325653c87274f66664526d8ca55baaaa5251b4f822617b986
7
+ data.tar.gz: 63aceaac41dd2ea797f92e7335a381bea5d1bdd2f7388c583431323e7ac9fae0855a404a84fbed70222130bd5eded126dae5385be2291d76c91021633d03a3bb
@@ -1,3 +1,17 @@
1
+ ## 0.12.3 - 2020-08-22
2
+
3
+ ### Changed
4
+
5
+ * Allow any object responding to `#to_sym` when setting a radio button value
6
+
7
+ ### Fixed
8
+
9
+ * Error in the AcroForm appearance generator for text fields when the font is
10
+ not found in the default resources
11
+ * Parsing of long numbers when reading a file from IO
12
+ * Usage of unsupported method for Ruby 2.4 so that all tests pass again
13
+
14
+
1
15
  ## 0.12.2 - 2020-08-17
2
16
 
3
17
  ### Fixed
@@ -177,7 +177,7 @@ module HexaPDF
177
177
  def parse(contents, processor = nil, &block) #:yields: object, params
178
178
  raise ArgumentError, "Argument processor or block is needed" if processor.nil? && block.nil?
179
179
  if processor.nil?
180
- block.singleton_class.alias_method(:process, :call)
180
+ block.singleton_class.send(:alias_method, :process, :call)
181
181
  processor = block
182
182
  end
183
183
 
@@ -249,17 +249,18 @@ module HexaPDF
249
249
  #
250
250
  # See: PDF1.7 s7.3.3
251
251
  def parse_number
252
- if (val = @ss.scan(/[+-]?\d++(?!\.)/))
252
+ val = scan_until(WHITESPACE_OR_DELIMITER_RE) || @ss.scan(/.*/)
253
+ if val.match?(/\A[+-]?\d++(?!\.)\z/)
253
254
  tmp = val.to_i
254
255
  # Handle object references, see PDF1.7 s7.3.10
255
256
  prepare_string_scanner(10)
256
257
  tmp = Reference.new(tmp, @ss[1].to_i) if @ss.scan(REFERENCE_RE)
257
258
  tmp
258
- elsif (val = @ss.scan(/[+-]?(?:\d+\.\d*|\.\d+)/))
259
+ elsif val.match?(/\A[+-]?(?:\d+\.\d*|\.\d+)\z/)
259
260
  val << '0' if val.getbyte(-1) == 46 # dot '.'
260
261
  Float(val)
261
262
  else
262
- parse_keyword
263
+ TOKEN_CACHE[val] # val is keyword
263
264
  end
264
265
  end
265
266
 
@@ -206,6 +206,10 @@ module HexaPDF
206
206
  # * The font, font size and font color are taken from the associated field's default
207
207
  # appearance string. See VariableTextField.
208
208
  #
209
+ # If the font is not usable by HexaPDF (which may be due to a variety of reasons, e.g. no
210
+ # associated information in the form's default resources), the font specified by the
211
+ # configuration option +acro_form.fallback_font+ will be used.
212
+ #
209
213
  # * The widget's rectangle /Rect must be defined. If the height is zero, it is auto-sized
210
214
  # based on the font size. If additionally the font size is zero, a font size of
211
215
  # +acro_form.default_font_size+ is used. If the width is zero, the
@@ -222,7 +226,7 @@ module HexaPDF
222
226
  def create_text_appearances
223
227
  font_name, font_size = @field.parse_default_appearance_string
224
228
  default_resources = @document.acro_form.default_resources
225
- font = default_resources.font(font_name).font_wrapper
229
+ font = default_resources.font(font_name).font_wrapper rescue nil
226
230
  unless font
227
231
  fallback_font_name, fallback_font_options = @document.config['acro_form.fallback_font']
228
232
  if fallback_font_name
@@ -134,8 +134,8 @@ module HexaPDF
134
134
  # Check boxes:: For check boxes that are in the on state the value +true+ is returned.
135
135
  # Otherwise +false+ is returned.
136
136
  #
137
- # Radio buttons:: If no radio button is selected, +nil+ is returned. Otherwise the name of
138
- # the specific radio button that is selected is returned.
137
+ # Radio buttons:: If no radio button is selected, +nil+ is returned. Otherwise the value (a
138
+ # Symbol) of the specific radio button that is selected is returned.
139
139
  def field_value
140
140
  normalized_field_value(:V)
141
141
  end
@@ -149,7 +149,8 @@ module HexaPDF
149
149
  # +false+ for unchecking it.
150
150
  #
151
151
  # Radio buttons:: To turn all radio buttons off, provide +nil+ as value. Otherwise provide
152
- # the name of a radio button that should be turned on.
152
+ # the value (a Symbol or an object responding to +#to_sym+) of a radio
153
+ # button that should be turned on.
153
154
  def field_value=(value)
154
155
  normalized_field_value_set(:V, value)
155
156
  end
@@ -179,7 +180,7 @@ module HexaPDF
179
180
  end
180
181
  end
181
182
 
182
- # Returns the name used for setting the check box to the on state.
183
+ # Returns the name (a Symbol) used for setting the check box to the on state.
183
184
  #
184
185
  # Defaults to :Yes if no other name could be determined.
185
186
  def check_box_on_name
@@ -187,7 +188,8 @@ module HexaPDF
187
188
  find {|key| key != :Off } || :Yes
188
189
  end
189
190
 
190
- # Returns the array of values that can be used for the field value of the radio button.
191
+ # Returns the array of Symbol values that can be used for the field value of the radio
192
+ # button.
191
193
  def radio_button_values
192
194
  each_widget.map do |widget|
193
195
  widget.appearance&.normal_appearance&.value&.each_key&.find {|key| key != :Off }
@@ -200,8 +202,8 @@ module HexaPDF
200
202
  # default appearance.
201
203
  #
202
204
  # If the widget is created for a radio button field, the +value+ argument needs to set to
203
- # the value (a symbol) this widget represents. It can be used with #field_value= to set this
204
- # specific widget of the radio button set to on.
205
+ # the value (a Symbol or an object responding to +#to_sym+) this widget represents. It can
206
+ # be used with #field_value= to set this specific widget of the radio button set to on.
205
207
  #
206
208
  # See: Field#create_widget, AppearanceGenerator button field methods
207
209
  def create_widget(page, defaults: true, value: nil, **values)
@@ -209,8 +211,11 @@ module HexaPDF
209
211
  if check_box?
210
212
  widget[:AP] = {N: {Yes: nil, Off: nil}}
211
213
  elsif radio_button?
212
- raise ArgumentError, "Argument value has to be provided for radio buttons" unless value
213
- widget[:AP] = {N: {value => nil, Off: nil}}
214
+ unless value.respond_to?(:to_sym)
215
+ raise ArgumentError, "Argument 'value' has to be provided for radio buttons " \
216
+ "and needs to respond to #to_sym"
217
+ end
218
+ widget[:AP] = {N: {value.to_sym => nil, Off: nil}}
214
219
  end
215
220
  next unless defaults
216
221
  widget.border_style(color: 0, width: 1, style: (push_button? ? :beveled : :solid))
@@ -271,8 +276,8 @@ module HexaPDF
271
276
  value == true ? check_box_on_name : :Off
272
277
  elsif value.nil?
273
278
  :Off
274
- elsif radio_button_values.include?(value)
275
- value
279
+ elsif radio_button_values.include?(value.to_sym)
280
+ value.to_sym
276
281
  else
277
282
  @document.config['acro_form.on_invalid_value'].call(self, value)
278
283
  end
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.12.2'
40
+ VERSION = '0.12.3'
41
41
 
42
42
  end
@@ -121,6 +121,11 @@ module CommonTokenizerTests
121
121
  assert(token.kind_of?(HexaPDF::Tokenizer::Token))
122
122
  end
123
123
 
124
+ it "next_token: should not fail when reading super long numbers" do
125
+ create_tokenizer("1" + "0" * 10_000)
126
+ assert_equal(10**10_000, @tokenizer.next_token)
127
+ end
128
+
124
129
  it "next_object: works for all PDF object types, including array and dictionary" do
125
130
  create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
126
131
  true false null 123 34.5 (string) <4E6F76> /Name
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.12.2)>>
43
+ <</Producer(HexaPDF version 0.12.3)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.12.2)>>
75
+ <</Producer(HexaPDF version 0.12.3)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -495,18 +495,25 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
495
495
 
496
496
  describe "font resolution in case the referenced font is not usable" do
497
497
  before do
498
- def (@form.default_resources.font(:F1)).font_wrapper; nil; end
499
- @field.field_value = 'Test'
498
+ @doc.config['acro_form.fallback_font'] = ['Times', variant: :none]
499
+ @field[:V] = 'Test'
500
500
  end
501
501
 
502
- it "uses the fallback font if configured" do
503
- @doc.config['acro_form.fallback_font'] = ['Times', variant: :none]
502
+ it "uses the fallback font if the font is not usable" do
503
+ def (@form.default_resources.font(:F1)).font_wrapper; nil; end
504
504
  @generator.create_appearances
505
505
  assert_equal(:'Times-Roman', @widget[:AP][:N][:Resources][:Font][:F2][:BaseFont])
506
506
  end
507
507
 
508
+ it "uses the fallback font if the font is not found" do
509
+ @form.default_resources[:Font].delete(:F1)
510
+ @generator.create_appearances
511
+ assert_equal(:'Times-Roman', @widget[:AP][:N][:Resources][:Font][:F1][:BaseFont])
512
+ end
513
+
508
514
  it "fails if fallback fonts are disabled" do
509
515
  @doc.config['acro_form.fallback_font'] = nil
516
+ @form.default_resources[:Font].delete(:F1)
510
517
  msg = assert_raises(HexaPDF::Error) { @generator.create_appearances }
511
518
  assert_match(/Font.*not usable/, msg.message)
512
519
  end
@@ -140,7 +140,7 @@ describe HexaPDF::Type::AcroForm::ButtonField do
140
140
  it "sets a correct field value" do
141
141
  @field.create_widget(@doc.pages.add, value: :button1)
142
142
 
143
- @field.field_value = :button1
143
+ @field.field_value = "button1"
144
144
  assert_equal(:button1, @field[:V])
145
145
  @field.field_value = nil
146
146
  assert_equal(:Off, @field[:V])
@@ -158,7 +158,7 @@ describe HexaPDF::Type::AcroForm::ButtonField do
158
158
  end
159
159
 
160
160
  it "returns an array of possible values" do
161
- @field.create_widget(@doc.pages.add, value: :Test)
161
+ @field.create_widget(@doc.pages.add, value: "Test")
162
162
  @field.create_widget(@doc.pages.add, value: :x)
163
163
  @field.create_widget(@doc.pages.add, value: :y)
164
164
  assert_equal([:Test, :x, :y], @field.radio_button_values)
@@ -172,6 +172,7 @@ describe HexaPDF::Type::AcroForm::ButtonField do
172
172
  assert_equal(:solid, border_style.style)
173
173
  assert_equal([1], widget.background_color.components)
174
174
  assert_equal(:circle, widget.marker_style.style)
175
+ assert_equal({test: nil, Off: nil}, widget[:AP][:N].value)
175
176
  end
176
177
 
177
178
  it "always creates standalone widgets" do
@@ -181,6 +182,10 @@ describe HexaPDF::Type::AcroForm::ButtonField do
181
182
  it "fails if the value argument is not provided for create_widget" do
182
183
  assert_raises(ArgumentError) { @field.create_widget(@doc.pages.add) }
183
184
  end
185
+
186
+ it "fails if the value argument for create_widget doesn't respond to to_sym" do
187
+ assert_raises(ArgumentError) { @field.create_widget(@doc.pages.add, value: 5) }
188
+ end
184
189
  end
185
190
 
186
191
  it "returns a default field value" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-17 00:00:00.000000000 Z
11
+ date: 2020-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse