hexapdf 0.17.2 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/lib/hexapdf/cli/command.rb +7 -1
  4. data/lib/hexapdf/content/canvas.rb +2 -2
  5. data/lib/hexapdf/content/color_space.rb +19 -0
  6. data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
  7. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +4 -4
  8. data/lib/hexapdf/content/graphic_object/solid_arc.rb +111 -10
  9. data/lib/hexapdf/content/graphics_state.rb +167 -25
  10. data/lib/hexapdf/dictionary.rb +1 -1
  11. data/lib/hexapdf/dictionary_fields.rb +1 -1
  12. data/lib/hexapdf/document/signatures.rb +221 -0
  13. data/lib/hexapdf/encryption/security_handler.rb +3 -1
  14. data/lib/hexapdf/layout/style.rb +2 -1
  15. data/lib/hexapdf/object.rb +18 -0
  16. data/lib/hexapdf/parser.rb +3 -0
  17. data/lib/hexapdf/serializer.rb +2 -0
  18. data/lib/hexapdf/task/optimize.rb +46 -3
  19. data/lib/hexapdf/type/acro_form/appearance_generator.rb +4 -4
  20. data/lib/hexapdf/type/acro_form/form.rb +39 -28
  21. data/lib/hexapdf/type/acro_form/variable_text_field.rb +56 -18
  22. data/lib/hexapdf/type/annotations/widget.rb +3 -15
  23. data/lib/hexapdf/type/font.rb +5 -0
  24. data/lib/hexapdf/type/font_type3.rb +20 -0
  25. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +125 -0
  26. data/lib/hexapdf/version.rb +1 -1
  27. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +16 -8
  28. data/test/hexapdf/content/test_color_space.rb +26 -0
  29. data/test/hexapdf/content/test_graphics_state.rb +9 -1
  30. data/test/hexapdf/content/test_operator.rb +8 -3
  31. data/test/hexapdf/encryption/test_security_handler.rb +3 -1
  32. data/test/hexapdf/layout/test_style.rb +11 -0
  33. data/test/hexapdf/task/test_optimize.rb +26 -0
  34. data/test/hexapdf/test_dictionary.rb +1 -0
  35. data/test/hexapdf/test_dictionary_fields.rb +3 -2
  36. data/test/hexapdf/test_object.rb +28 -0
  37. data/test/hexapdf/test_parser.rb +11 -0
  38. data/test/hexapdf/test_writer.rb +2 -2
  39. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +8 -1
  40. data/test/hexapdf/type/acro_form/test_form.rb +15 -8
  41. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +18 -8
  42. data/test/hexapdf/type/test_font.rb +4 -0
  43. data/test/hexapdf/type/test_font_type3.rb +16 -1
  44. metadata +4 -2
@@ -499,6 +499,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
499
499
 
500
500
  it "creates the /N appearance stream according to the set string" do
501
501
  @field.field_value = 'Text'
502
+ @field.set_default_appearance_string(font_color: "red")
502
503
  @generator.create_appearances
503
504
  assert_operators(@widget[:AP][:N].stream,
504
505
  [[:begin_marked_content, [:Tx]],
@@ -507,6 +508,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
507
508
  [:clip_path_non_zero],
508
509
  [:end_path],
509
510
  [:set_font_and_size, [:F1, 6.641436]],
511
+ [:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
510
512
  [:begin_text],
511
513
  [:set_text_matrix, [1, 0, 0, 1, 2, 3.240724]],
512
514
  [:show_text, ["Text"]],
@@ -556,6 +558,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
556
558
 
557
559
  it "creates the /N appearance stream according to the set string" do
558
560
  @field.field_value = "Test\nValue"
561
+ @field.set_default_appearance_string(font_size: 10, font_color: "red")
559
562
  @generator.create_appearances
560
563
  assert_operators(@widget[:AP][:N].stream,
561
564
  [[:begin_marked_content, [:Tx]],
@@ -566,6 +569,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
566
569
  [:save_graphics_state],
567
570
  [:set_leading, [11.5625]],
568
571
  [:set_font_and_size, [:F1, 10]],
572
+ [:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
569
573
  [:begin_text],
570
574
  [:set_text_matrix, [1, 0, 0, 1, 2, 16.195]],
571
575
  [:show_text, ['Test']],
@@ -653,6 +657,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
653
657
 
654
658
  it "creates the /N appearance stream according to the set string" do
655
659
  @field.field_value = 'Text'
660
+ @field.set_default_appearance_string(font_size: 10, font_color: "red")
656
661
  @generator.create_appearances
657
662
  assert_operators(@widget[:AP][:N].stream,
658
663
  [[:begin_marked_content, [:Tx]],
@@ -661,6 +666,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
661
666
  [:clip_path_non_zero],
662
667
  [:end_path],
663
668
  [:set_font_and_size, [:F1, 10]],
669
+ [:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
664
670
  [:begin_text],
665
671
  [:set_text_matrix, [1, 0, 0, 1, 2.945, 6.41]],
666
672
  [:show_text_with_positioning, [['T', -416.5, 'e', -472, 'x', -611, 't']]],
@@ -721,6 +727,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
721
727
  it "creates the /N appearance stream" do
722
728
  @field[:I] = [1, 2]
723
729
  @field[:V] = ['b', 'c']
730
+ @field.set_default_appearance_string(font_size: 12, font_color: "red")
724
731
  @generator.create_appearances
725
732
  assert_operators(@widget[:AP][:N].stream,
726
733
  [[:begin_marked_content, [:Tx]],
@@ -734,7 +741,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
734
741
  [:save_graphics_state],
735
742
  [:set_leading, [13.875]],
736
743
  [:set_font_and_size, [:F1, 12]],
737
- [:set_device_gray_non_stroking_color, [0.0]],
744
+ [:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
738
745
  [:begin_text],
739
746
  [:set_text_matrix, [1, 0, 0, 1, 2, 23.609]],
740
747
  [:show_text, ["a"]],
@@ -8,6 +8,7 @@ describe HexaPDF::Type::AcroForm::Form do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
10
  @acro_form = @doc.add({Fields: []}, type: :XXAcroForm)
11
+ @doc.catalog[:AcroForm] = @acro_form
11
12
  end
12
13
 
13
14
  describe "signature flags" do
@@ -140,12 +141,13 @@ describe HexaPDF::Type::AcroForm::Form do
140
141
 
141
142
  def applies_variable_text_properties(method, **args)
142
143
  field = @acro_form.send(method, "field", **args, font: 'Times')
143
- font_name, font_size = field.parse_default_appearance_string
144
+ font_name, font_size, font_color = field.parse_default_appearance_string
144
145
  assert_equal(:'Times-Roman', @acro_form.default_resources.font(font_name)[:BaseFont])
145
146
  assert_equal(0, font_size)
147
+ assert_equal(HexaPDF::Content::ColorSpace::DeviceGray.new.color(0), font_color)
146
148
 
147
149
  field = @acro_form.send(method, "field", **args, font_options: {variant: :bold})
148
- font_name, font_size = field.parse_default_appearance_string
150
+ font_name, = field.parse_default_appearance_string
149
151
  assert_equal(:'Helvetica-Bold', @acro_form.default_resources.font(font_name)[:BaseFont])
150
152
 
151
153
  field = @acro_form.send(method, "field", **args, font_size: 10)
@@ -153,6 +155,10 @@ describe HexaPDF::Type::AcroForm::Form do
153
155
  assert_equal(:Helvetica, @acro_form.default_resources.font(font_name)[:BaseFont])
154
156
  assert_equal(10, font_size)
155
157
 
158
+ field = @acro_form.send(method, "field", **args, font_color: "red")
159
+ _, _, font_color = field.parse_default_appearance_string
160
+ assert_equal(HexaPDF::Content::ColorSpace::DeviceRGB.new.color(255, 0, 0), font_color)
161
+
156
162
  field = @acro_form.send(method, "field", **args, font: 'Courier', font_size: 10, align: :center)
157
163
  font_name, font_size = field.parse_default_appearance_string
158
164
  assert_equal(:Courier, @acro_form.default_resources.font(font_name)[:BaseFont])
@@ -229,16 +235,17 @@ describe HexaPDF::Type::AcroForm::Form do
229
235
  describe "set_default_appearance_string" do
230
236
  it "uses sane default values if no arguments are provided" do
231
237
  @acro_form.set_default_appearance_string
232
- assert_equal("0 g /F1 0 Tf", @acro_form[:DA])
238
+ assert_equal("0.0 g /F1 0 Tf", @acro_form[:DA])
233
239
  font = @acro_form.default_resources.font(:F1)
234
240
  assert(font)
235
241
  assert_equal(:Helvetica, font[:BaseFont])
236
242
  end
237
243
 
238
- it "allows specifying the used font and font size" do
239
- @acro_form.set_default_appearance_string(font: 'Times', font_size: 10)
240
- assert_equal("0 g /F1 10 Tf", @acro_form[:DA])
241
- assert_equal(:'Times-Roman', @acro_form.default_resources.font(:F1)[:BaseFont])
244
+ it "allows specifying the used font, font size and font color" do
245
+ @acro_form.set_default_appearance_string(font: 'Times', font_options: {variant: :bold},
246
+ font_size: 10, font_color: "red")
247
+ assert_equal("1.0 0.0 0.0 rg /F1 10 Tf", @acro_form[:DA])
248
+ assert_equal(:'Times-Bold', @acro_form.default_resources.font(:F1)[:BaseFont])
242
249
  end
243
250
  end
244
251
 
@@ -333,7 +340,7 @@ describe HexaPDF::Type::AcroForm::Form do
333
340
 
334
341
  it "set the default appearance string, though optional, to a valid value to avoid problems" do
335
342
  assert(@acro_form.validate)
336
- assert_equal("0 g /F1 0 Tf", @acro_form[:DA])
343
+ assert_equal("0.0 g /F1 0 Tf", @acro_form[:DA])
337
344
  end
338
345
 
339
346
  describe "automatically creates the terminal fields; appearances" do
@@ -31,7 +31,7 @@ describe HexaPDF::Type::AcroForm::VariableTextField do
31
31
  end
32
32
  end
33
33
 
34
- describe "set_default_appearance_string" do
34
+ describe "set_default_appearance_string / self.create_appearance_string" do
35
35
  it "creates the AcroForm object if it doesn't exist" do
36
36
  @doc.catalog.delete(:AcroForm)
37
37
  @field.set_default_appearance_string
@@ -40,7 +40,7 @@ describe HexaPDF::Type::AcroForm::VariableTextField do
40
40
 
41
41
  it "uses sane default values if no arguments are provided" do
42
42
  @field.set_default_appearance_string
43
- assert_equal("0 g /F1 0 Tf", @field[:DA])
43
+ assert_equal("0.0 g /F1 0 Tf", @field[:DA])
44
44
  font = @doc.acro_form.default_resources.font(:F1)
45
45
  assert(font)
46
46
  assert_equal(:Helvetica, font[:BaseFont])
@@ -48,36 +48,46 @@ describe HexaPDF::Type::AcroForm::VariableTextField do
48
48
 
49
49
  it "allows specifying the font" do
50
50
  @field.set_default_appearance_string(font: 'Times')
51
- assert_equal("0 g /F2 0 Tf", @field[:DA])
51
+ assert_equal("0.0 g /F2 0 Tf", @field[:DA])
52
52
  assert_equal(:'Times-Roman', @doc.acro_form.default_resources.font(:F2)[:BaseFont])
53
53
  end
54
54
 
55
55
  it "allows specifying the font options" do
56
56
  @field.set_default_appearance_string(font_options: {variant: :italic})
57
- assert_equal("0 g /F2 0 Tf", @field[:DA])
57
+ assert_equal("0.0 g /F2 0 Tf", @field[:DA])
58
58
  assert_equal(:'Helvetica-Oblique', @doc.acro_form.default_resources.font(:F2)[:BaseFont])
59
59
  end
60
60
 
61
61
  it "allows specifying the font size" do
62
62
  @field.set_default_appearance_string(font_size: 10)
63
- assert_equal("0 g /F1 10 Tf", @field[:DA])
63
+ assert_equal("0.0 g /F1 10 Tf", @field[:DA])
64
+ end
65
+
66
+ it "allows specifying the font color" do
67
+ @field.set_default_appearance_string(font_color: "red")
68
+ assert_equal("1.0 0.0 0.0 rg /F1 0 Tf", @field[:DA])
64
69
  end
65
70
  end
66
71
 
67
72
  describe "parse_default_appearance_string" do
73
+ before do
74
+ @color = HexaPDF::Content::ColorSpace.prenormalized_device_color([1])
75
+ end
76
+
68
77
  it "parses the default appearance string of the field" do
69
78
  @field[:DA] = "1 g //F1 20 Tf 5 w /F2 10 Tf"
70
- assert_equal([:F2, 10], @field.parse_default_appearance_string)
79
+ assert_equal([:F2, 10, @color], @field.parse_default_appearance_string)
71
80
  end
72
81
 
73
82
  it "uses the default appearance string of a parent field" do
74
83
  parent = @doc.add({DA: "/F1 15 Tf"}, type: :XXAcroFormField)
75
84
  @field[:Parent] = parent
76
- assert_equal([:F1, 15], @field.parse_default_appearance_string)
85
+ assert_equal([:F1, 15, nil], @field.parse_default_appearance_string)
77
86
  end
78
87
 
79
88
  it "uses the global default appearance string" do
80
- assert_equal([:F1, 0], @field.parse_default_appearance_string)
89
+ assert_equal([:F1, 0, HexaPDF::Content::ColorSpace.prenormalized_device_color([0])],
90
+ @field.parse_default_appearance_string)
81
91
  end
82
92
 
83
93
  it "fails if no /DA value is set" do
@@ -64,4 +64,8 @@ describe HexaPDF::Type::Font do
64
64
  assert_equal(5, @font.font_file)
65
65
  end
66
66
  end
67
+
68
+ it "returns the glyph scaling factor" do
69
+ assert_equal(0.001, @font.glyph_scaling_factor)
70
+ end
67
71
  end
@@ -9,10 +9,25 @@ describe HexaPDF::Type::FontType3 do
9
9
  @doc = HexaPDF::Document.new
10
10
  @font = @doc.add({Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
11
11
  FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
12
- FontBBox: [0, 0, 100, 100], FontMatrix: [1, 0, 0, 1, 0, 0],
12
+ FontBBox: [0, 100, 100, 0], FontMatrix: [0.002, 0, 0, 0.002, 0, 0],
13
13
  CharProcs: {}})
14
14
  end
15
15
 
16
+ describe "bounding_box" do
17
+ it "returns the font's bounding box" do
18
+ assert_equal([0, 0, 100, 100], @font.bounding_box)
19
+ end
20
+
21
+ it "inverts the y-values if necessary based on /FontMatrix" do
22
+ @font[:FontMatrix][3] *= -1
23
+ assert_equal([0, -100, 100, 0], @font.bounding_box)
24
+ end
25
+ end
26
+
27
+ it "returns the glyph scaling factor" do
28
+ assert_equal(0.002, @font.glyph_scaling_factor)
29
+ end
30
+
16
31
  describe "validation" do
17
32
  it "works for valid objects" do
18
33
  assert(@font.validate)
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.17.2
4
+ version: 0.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-26 00:00:00.000000000 Z
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -254,6 +254,7 @@ files:
254
254
  - lib/hexapdf/document/fonts.rb
255
255
  - lib/hexapdf/document/images.rb
256
256
  - lib/hexapdf/document/pages.rb
257
+ - lib/hexapdf/document/signatures.rb
257
258
  - lib/hexapdf/encryption.rb
258
259
  - lib/hexapdf/encryption/aes.rb
259
260
  - lib/hexapdf/encryption/arc4.rb
@@ -396,6 +397,7 @@ files:
396
397
  - lib/hexapdf/type/page.rb
397
398
  - lib/hexapdf/type/page_tree_node.rb
398
399
  - lib/hexapdf/type/resources.rb
400
+ - lib/hexapdf/type/signature/adbe_pkcs7_detached.rb
399
401
  - lib/hexapdf/type/trailer.rb
400
402
  - lib/hexapdf/type/viewer_preferences.rb
401
403
  - lib/hexapdf/type/xref_stream.rb