hexapdf 0.26.2 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +115 -1
  3. data/README.md +1 -1
  4. data/examples/013-text_layouter_shapes.rb +8 -8
  5. data/examples/016-frame_automatic_box_placement.rb +3 -3
  6. data/examples/017-frame_text_flow.rb +3 -3
  7. data/examples/019-acro_form.rb +14 -3
  8. data/examples/020-column_box.rb +3 -3
  9. data/examples/023-images.rb +30 -0
  10. data/lib/hexapdf/cli/info.rb +5 -1
  11. data/lib/hexapdf/cli/inspect.rb +2 -2
  12. data/lib/hexapdf/cli/split.rb +8 -8
  13. data/lib/hexapdf/cli/watermark.rb +2 -2
  14. data/lib/hexapdf/configuration.rb +3 -2
  15. data/lib/hexapdf/content/canvas.rb +8 -3
  16. data/lib/hexapdf/dictionary.rb +4 -17
  17. data/lib/hexapdf/document/destinations.rb +42 -5
  18. data/lib/hexapdf/document/signatures.rb +265 -48
  19. data/lib/hexapdf/document.rb +6 -10
  20. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  21. data/lib/hexapdf/importer.rb +35 -27
  22. data/lib/hexapdf/layout/list_box.rb +1 -5
  23. data/lib/hexapdf/object.rb +5 -0
  24. data/lib/hexapdf/parser.rb +14 -0
  25. data/lib/hexapdf/revision.rb +15 -12
  26. data/lib/hexapdf/revisions.rb +7 -1
  27. data/lib/hexapdf/tokenizer.rb +15 -9
  28. data/lib/hexapdf/type/acro_form/appearance_generator.rb +174 -128
  29. data/lib/hexapdf/type/acro_form/button_field.rb +5 -3
  30. data/lib/hexapdf/type/acro_form/choice_field.rb +2 -0
  31. data/lib/hexapdf/type/acro_form/field.rb +11 -5
  32. data/lib/hexapdf/type/acro_form/form.rb +61 -8
  33. data/lib/hexapdf/type/acro_form/signature_field.rb +2 -0
  34. data/lib/hexapdf/type/acro_form/text_field.rb +12 -2
  35. data/lib/hexapdf/type/annotations/widget.rb +3 -0
  36. data/lib/hexapdf/type/catalog.rb +1 -1
  37. data/lib/hexapdf/type/font_true_type.rb +14 -0
  38. data/lib/hexapdf/type/object_stream.rb +2 -2
  39. data/lib/hexapdf/type/outline.rb +19 -1
  40. data/lib/hexapdf/type/outline_item.rb +72 -14
  41. data/lib/hexapdf/type/page.rb +95 -64
  42. data/lib/hexapdf/type/resources.rb +13 -17
  43. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +16 -2
  44. data/lib/hexapdf/type/signature.rb +10 -0
  45. data/lib/hexapdf/version.rb +1 -1
  46. data/lib/hexapdf/writer.rb +5 -3
  47. data/test/hexapdf/content/test_canvas.rb +5 -0
  48. data/test/hexapdf/document/test_destinations.rb +41 -0
  49. data/test/hexapdf/document/test_pages.rb +2 -2
  50. data/test/hexapdf/document/test_signatures.rb +139 -19
  51. data/test/hexapdf/encryption/test_aes.rb +1 -1
  52. data/test/hexapdf/filter/test_predictor.rb +0 -1
  53. data/test/hexapdf/layout/test_box.rb +2 -1
  54. data/test/hexapdf/layout/test_column_box.rb +1 -1
  55. data/test/hexapdf/layout/test_list_box.rb +1 -1
  56. data/test/hexapdf/test_document.rb +2 -8
  57. data/test/hexapdf/test_importer.rb +27 -6
  58. data/test/hexapdf/test_parser.rb +19 -2
  59. data/test/hexapdf/test_revision.rb +15 -14
  60. data/test/hexapdf/test_revisions.rb +63 -12
  61. data/test/hexapdf/test_stream.rb +1 -1
  62. data/test/hexapdf/test_tokenizer.rb +10 -1
  63. data/test/hexapdf/test_writer.rb +11 -3
  64. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +135 -56
  65. data/test/hexapdf/type/acro_form/test_button_field.rb +6 -1
  66. data/test/hexapdf/type/acro_form/test_choice_field.rb +4 -0
  67. data/test/hexapdf/type/acro_form/test_field.rb +4 -4
  68. data/test/hexapdf/type/acro_form/test_form.rb +65 -0
  69. data/test/hexapdf/type/acro_form/test_signature_field.rb +4 -0
  70. data/test/hexapdf/type/acro_form/test_text_field.rb +13 -0
  71. data/test/hexapdf/type/signature/common.rb +54 -0
  72. data/test/hexapdf/type/signature/test_adbe_pkcs7_detached.rb +21 -0
  73. data/test/hexapdf/type/test_catalog.rb +5 -2
  74. data/test/hexapdf/type/test_font_true_type.rb +20 -0
  75. data/test/hexapdf/type/test_object_stream.rb +2 -1
  76. data/test/hexapdf/type/test_outline.rb +4 -1
  77. data/test/hexapdf/type/test_outline_item.rb +62 -1
  78. data/test/hexapdf/type/test_page.rb +103 -45
  79. data/test/hexapdf/type/test_page_tree_node.rb +4 -2
  80. data/test/hexapdf/type/test_resources.rb +0 -5
  81. data/test/hexapdf/type/test_signature.rb +8 -0
  82. data/test/test_helper.rb +1 -1
  83. metadata +61 -4
@@ -94,6 +94,11 @@ describe HexaPDF::Type::Page do
94
94
  @page = @doc.pages.add
95
95
  end
96
96
 
97
+ it "returns the crop box by default" do
98
+ @page[:CropBox] = [0, 0, 100, 200]
99
+ assert_equal([0, 0, 100, 200], @page.box)
100
+ end
101
+
97
102
  it "returns the correct media box" do
98
103
  @page[:MediaBox] = :media
99
104
  assert_equal(:media, @page.box(:media))
@@ -150,15 +155,25 @@ describe HexaPDF::Type::Page do
150
155
  @page = @doc.pages.add
151
156
  end
152
157
 
153
- it "returns :portrait for appropriate media boxes and rotation values" do
154
- @page.box(:media, [0, 0, 100, 300])
158
+ it "uses the crop box by default" do
159
+ @page[:CropBox] = [0, 0, 200, 100]
160
+ assert_equal(:landscape, @page.orientation)
161
+ end
162
+
163
+ it "uses the specified box for determining the orientation" do
164
+ @page[:ArtBox] = [0, 0, 200, 100]
165
+ assert_equal(:landscape, @page.orientation(:art))
166
+ end
167
+
168
+ it "returns :portrait for appropriate boxes and rotation values" do
169
+ @page.box(:crop, [0, 0, 100, 300])
155
170
  assert_equal(:portrait, @page.orientation)
156
171
  @page[:Rotate] = 0
157
172
  assert_equal(:portrait, @page.orientation)
158
173
  @page[:Rotate] = 180
159
174
  assert_equal(:portrait, @page.orientation)
160
175
 
161
- @page.box(:media, [0, 0, 300, 100])
176
+ @page.box(:crop, [0, 0, 300, 100])
162
177
  @page[:Rotate] = 90
163
178
  assert_equal(:portrait, @page.orientation)
164
179
  @page[:Rotate] = 270
@@ -166,14 +181,14 @@ describe HexaPDF::Type::Page do
166
181
  end
167
182
 
168
183
  it "returns :landscape for appropriate media boxes and rotation values" do
169
- @page.box(:media, [0, 0, 300, 100])
184
+ @page.box(:crop, [0, 0, 300, 100])
170
185
  assert_equal(:landscape, @page.orientation)
171
186
  @page[:Rotate] = 0
172
187
  assert_equal(:landscape, @page.orientation)
173
188
  @page[:Rotate] = 180
174
189
  assert_equal(:landscape, @page.orientation)
175
190
 
176
- @page.box(:media, [0, 0, 100, 300])
191
+ @page.box(:crop, [0, 0, 100, 300])
177
192
  @page[:Rotate] = 90
178
193
  assert_equal(:landscape, @page.orientation)
179
194
  @page[:Rotate] = 270
@@ -204,36 +219,72 @@ describe HexaPDF::Type::Page do
204
219
 
205
220
  describe "flatten" do
206
221
  it "adjust all page boxes" do
207
- @page.box(:crop, @page.box)
208
- @page.box(:bleed, @page.box)
209
- @page.box(:trim, @page.box)
210
- @page.box(:art, @page.box)
222
+ @page.box(:crop, [0, 0, 1, 2])
223
+ @page.box(:bleed, [0, 0, 2, 3])
224
+ @page.box(:trim, [0, 0, 3, 4])
225
+ @page.box(:art, [0, 0, 4, 5])
211
226
 
212
227
  @page.rotate(90, flatten: true)
213
- box = [-300, 50, -100, 200]
214
- assert_equal(box, @page.box(:media).value)
215
- assert_equal(box, @page.box(:crop).value)
216
- assert_equal(box, @page.box(:bleed).value)
217
- assert_equal(box, @page.box(:trim).value)
218
- assert_equal(box, @page.box(:art).value)
228
+ assert_equal([-298, 50, -98, 200], @page.box(:media).value)
229
+ assert_equal([0, 0, 2, 1], @page.box(:crop).value)
230
+ assert_equal([-1, 0, 2, 2], @page.box(:bleed).value)
231
+ assert_equal([-2, 0, 2, 3], @page.box(:trim).value)
232
+ assert_equal([-3, 0, 2, 4], @page.box(:art).value)
219
233
  end
220
234
 
221
235
  it "works correctly for 90 degrees" do
222
236
  @page.rotate(90, flatten: true)
223
- assert_equal([-300, 50, -100, 200], @page.box(:media).value)
224
- assert_equal(" q 0 1 -1 0 0 0 cm Q ", @page.contents)
237
+ assert_equal([0, 0, 200, 150], @page.box(:media).value)
238
+ assert_equal(" q 0 1 -1 0 300 -50 cm Q ", @page.contents)
225
239
  end
226
240
 
227
241
  it "works correctly for 180 degrees" do
228
242
  @page.rotate(180, flatten: true)
229
- assert_equal([-200, -300, -50, -100], @page.box(:media).value)
230
- assert_equal(" q -1 0 0 -1 0 0 cm Q ", @page.contents)
243
+ assert_equal([0, 0, 150, 200], @page.box(:media).value)
244
+ assert_equal(" q -1 0 0 -1 200 300 cm Q ", @page.contents)
231
245
  end
232
246
 
233
247
  it "works correctly for 270 degrees" do
234
248
  @page.rotate(270, flatten: true)
235
- assert_equal([100, -200, 300, -50], @page.box(:media).value)
236
- assert_equal(" q 0 -1 1 0 0 0 cm Q ", @page.contents)
249
+ assert_equal([0, 0, 200, 150], @page.box(:media).value)
250
+ assert_equal(" q 0 -1 1 0 -100 200 cm Q ", @page.contents)
251
+ end
252
+
253
+ describe "annotations" do
254
+ before do
255
+ @appearance = @doc.add({Type: :XObject, Subtype: :Form, BBox: [-10, -5, 50, 20]}, stream: "")
256
+ @annot = @doc.add({Type: :Annot, Subtype: :Widget, Rect: [100, 100, 160, 125],
257
+ QuadPoints: [0, 0, 100, 200, 300, 400, 500, 600],
258
+ AP: {N: @appearance}})
259
+ @page[:Annots] = [@annot]
260
+ end
261
+
262
+ it "rotates the /Rect entry" do
263
+ @page.rotate(90, flatten: true)
264
+ assert_equal([175, 50, 200, 110], @annot[:Rect].value)
265
+ end
266
+
267
+ it "rotates all (x,y) pairs in the /QuadPoints entry" do
268
+ @page.rotate(90, flatten: true)
269
+ assert_equal([300, -50, 100, 50, -100, 250, -300, 450],
270
+ @annot[:QuadPoints])
271
+ end
272
+
273
+ it "applies the needed matrix to the annotation's appearance stream's /Matrix entry" do
274
+ @page.rotate(90, flatten: true)
275
+ assert_equal([0, 1, -1, 0, 300, -50], @appearance[:Matrix])
276
+
277
+ @page.rotate(90, flatten: true)
278
+ assert_equal([-1, 0, 0, -1, 200, 300], @appearance[:Matrix])
279
+ end
280
+
281
+ it "modified the /R entry in the appearance characteristics dictionary of a widget annotation" do
282
+ @page.rotate(90, flatten: true)
283
+ assert_equal(90, @annot[:MK][:R])
284
+
285
+ @page.rotate(90, flatten: true)
286
+ assert_equal(180, @annot[:MK][:R])
287
+ end
237
288
  end
238
289
  end
239
290
 
@@ -405,8 +456,8 @@ describe HexaPDF::Type::Page do
405
456
  [:restore_graphics_state]])
406
457
  end
407
458
 
408
- it "works correctly if the page has its origin not at (0,0)" do
409
- @page.box(:media, [-10, -5, 100, 300])
459
+ it "works correctly if the page has its crop box origin not at (0,0)" do
460
+ @page.box(:crop, [-10, -5, 100, 300])
410
461
  @page.canvas(type: :underlay).line_width = 2
411
462
  @page.canvas(type: :page).line_width = 2
412
463
  @page.canvas(type: :overlay).line_width = 2
@@ -427,6 +478,13 @@ describe HexaPDF::Type::Page do
427
478
  [:restore_graphics_state]])
428
479
  end
429
480
 
481
+ it "allows disabling the origin translation" do
482
+ @page.box(:crop, [-10, -5, 100, 300])
483
+ @page.canvas(translate_origin: false).line_width = 2
484
+
485
+ assert_page_operators(@page, [[:set_line_width, [2]]])
486
+ end
487
+
430
488
  it "fails if the page canvas is requested for a page with existing contents" do
431
489
  @page.contents = "q Q"
432
490
  assert_raises(HexaPDF::Error) { @page.canvas }
@@ -473,25 +531,30 @@ describe HexaPDF::Type::Page do
473
531
  @canvas = @page.canvas(type: :overlay)
474
532
  end
475
533
 
476
- it "does nothing if the page doesn't have any annotations" do
534
+ it "does nothing and returns the argument as array if the page doesn't have any annotations" do
535
+ annots = @page[:Annots]
536
+
477
537
  @page.delete(:Annots)
478
538
  result = @page.flatten_annotations
479
539
  assert(result.empty?)
480
540
  assert_operators(@canvas.contents, [])
541
+
542
+ result = @page.flatten_annotations(annots)
543
+ assert_kind_of(Array, result)
544
+ assert_equal([@annot1, @annot2], result)
545
+ assert_operators(@canvas.contents, [])
481
546
  end
482
547
 
483
548
  it "flattens all annotations of the page by default" do
484
549
  result = @page.flatten_annotations
485
550
  assert(result.empty?)
486
551
  assert_operators(@canvas.contents, [[:save_graphics_state],
487
- [:save_graphics_state],
488
552
  [:concatenate_matrix, [1.0, 0, 0, 1.0, 110, 105]],
489
553
  [:paint_xobject, [:XO1]],
490
554
  [:restore_graphics_state],
491
555
  [:save_graphics_state],
492
556
  [:concatenate_matrix, [1.0, 0, 0, 1.0, 20, 15]],
493
557
  [:paint_xobject, [:XO1]],
494
- [:restore_graphics_state],
495
558
  [:restore_graphics_state]])
496
559
  assert(@annot1.null?)
497
560
  assert(@annot2.null?)
@@ -521,10 +584,8 @@ describe HexaPDF::Type::Page do
521
584
  assert(result.empty?)
522
585
  assert(@annot1.null?)
523
586
  assert_operators(@canvas.contents, [[:save_graphics_state],
524
- [:save_graphics_state],
525
587
  [:concatenate_matrix, [1.0, 0, 0, 1.0, 20, 15]],
526
588
  [:paint_xobject, [:XO1]],
527
- [:restore_graphics_state],
528
589
  [:restore_graphics_state]])
529
590
  end
530
591
 
@@ -534,10 +595,8 @@ describe HexaPDF::Type::Page do
534
595
  assert(result.empty?)
535
596
  assert(@annot1.null?)
536
597
  assert_operators(@canvas.contents, [[:save_graphics_state],
537
- [:save_graphics_state],
538
598
  [:concatenate_matrix, [1.0, 0, 0, 1.0, 20, 15]],
539
599
  [:paint_xobject, [:XO1]],
540
- [:restore_graphics_state],
541
600
  [:restore_graphics_state]])
542
601
  end
543
602
 
@@ -547,56 +606,55 @@ describe HexaPDF::Type::Page do
547
606
  assert_equal([@annot1], result)
548
607
  refute(@annot1.empty?)
549
608
  assert_operators(@canvas.contents, [[:save_graphics_state],
550
- [:save_graphics_state],
551
609
  [:concatenate_matrix, [1.0, 0, 0, 1.0, 20, 15]],
552
610
  [:paint_xobject, [:XO1]],
553
- [:restore_graphics_state],
554
611
  [:restore_graphics_state]])
555
612
  end
556
613
 
557
- it "adjusts the position to counter the translation in #canvas based on the page's media box" do
558
- @page[:MediaBox] = [-15, -15, 100, 100]
614
+ it "potentially adjusts the origin so that it is always in (0,0)" do
615
+ @canvas.translate(-15, -15)
559
616
  @page.flatten_annotations
560
- assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 15, 15]], range: 1)
617
+ assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 15, 15]], range: 2)
561
618
  end
562
619
 
563
620
  it "adjusts the position in case the form /Matrix has an offset" do
564
621
  @appearance[:Matrix] = [1, 0, 0, 1, 15, 15]
565
622
  @page.flatten_annotations
566
- assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 95, 90]], range: 2)
623
+ assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 95, 90]], range: 1)
567
624
  end
568
625
 
569
626
  it "adjusts the position for an appearance with a 90 degree rotation" do
570
627
  @appearance[:Matrix] = [0, 1, -1, 0, 0, 0]
571
628
  @annot1[:Rect] = [100, 100, 125, 160]
572
629
  @page.flatten_annotations
573
- assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 120, 110]], range: 2)
630
+ assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 120, 110]], range: 1)
574
631
  end
575
632
 
576
633
  it "adjusts the position for an appearance with a -90 degree rotation" do
577
634
  @appearance[:Matrix] = [0, -1, 1, 0, 0, 0]
578
635
  @annot1[:Rect] = [100, 100, 125, 160]
579
636
  @page.flatten_annotations
580
- assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 105, 150]], range: 2)
637
+ assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 105, 150]], range: 1)
581
638
  end
582
639
 
583
640
  it "adjusts the position for an appearance with a 180 degree rotation" do
584
641
  @appearance[:Matrix] = [-1, 0, 0, -1, 0, 0]
585
642
  @page.flatten_annotations
586
- assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 150, 120]], range: 2)
643
+ assert_operators(@canvas.contents, [:concatenate_matrix, [1, 0, 0, 1, 150, 120]], range: 1)
587
644
  end
588
645
 
589
- it "ignores an appearance with a rotation that is not a mulitple of 90" do
590
- @appearance[:Matrix] = [-1, 0.5, 0.5, -1, 0, 0]
591
- result = @page.flatten_annotations
592
- assert_equal([@annot1, @annot2], result)
593
- assert_operators(@canvas.contents, [[:save_graphics_state], [:restore_graphics_state]])
646
+ it "correctly positions and scales an appearance with a custom rotation" do
647
+ @appearance[:Matrix] = [0.707106, 0.707106, -0.707106, 0.707106, 10, 30]
648
+ @page.flatten_annotations
649
+ assert_operators(@canvas.contents,
650
+ [:concatenate_matrix, [0.998269, 0.0, 0.0, 0.415946, 111.21318, 80.60659]],
651
+ range: 1)
594
652
  end
595
653
 
596
654
  it "scales the appearance to fit into the annotations's rectangle" do
597
655
  @annot1[:Rect] = [100, 100, 130, 150]
598
656
  @page.flatten_annotations
599
- assert_operators(@canvas.contents, [:concatenate_matrix, [0.5, 0, 0, 2, 110, 105]], range: 2)
657
+ assert_operators(@canvas.contents, [:concatenate_matrix, [0.5, 0, 0, 2, 110, 105]], range: 1)
600
658
  end
601
659
  end
602
660
 
@@ -241,11 +241,13 @@ describe HexaPDF::Type::PageTreeNode do
241
241
 
242
242
  it "moves the page to the correct location within the same parent node" do
243
243
  @root.move_page(2, 4)
244
- assert_equal([@pages[0], @pages[1], @pages[3], @pages[4], @pages[2], *@pages[5..-1]], @root.each_page.to_a)
244
+ assert_equal([@pages[0], @pages[1], @pages[3], @pages[4], @pages[2], *@pages[5..-1]],
245
+ @root.each_page.to_a)
245
246
  assert(@root.validate)
246
247
 
247
248
  @root.move_page(4, 3)
248
- assert_equal([@pages[0], @pages[1], @pages[3], @pages[2], @pages[4], *@pages[5..-1]], @root.each_page.to_a)
249
+ assert_equal([@pages[0], @pages[1], @pages[3], @pages[2], @pages[4], *@pages[5..-1]],
250
+ @root.each_page.to_a)
249
251
  assert(@root.validate)
250
252
  end
251
253
 
@@ -189,11 +189,6 @@ describe HexaPDF::Type::Resources do
189
189
  end
190
190
 
191
191
  describe "validation" do
192
- it "assigns the default value if ProcSet is not set" do
193
- @res.validate
194
- assert_equal([:PDF, :Text, :ImageB, :ImageC, :ImageI], @res[:ProcSet].value)
195
- end
196
-
197
192
  it "handles an invalid ProcSet containing a single value instead of an array" do
198
193
  @res[:ProcSet] = :PDF
199
194
  @res.validate
@@ -128,4 +128,12 @@ describe HexaPDF::Type::Signature do
128
128
  assert_kind_of(OpenSSL::X509::Store, store)
129
129
  assert(kwargs[:allow_self_signed])
130
130
  end
131
+
132
+ describe "perform_validation" do
133
+ it "upgrades the version to 2.0 if the /SubFilter needs it" do
134
+ refute(@sig.validate(auto_correct: false))
135
+ assert(@sig.validate(auto_correct: true))
136
+ assert_equal('2.0', @doc.version)
137
+ end
138
+ end
131
139
  end
data/test/test_helper.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  begin
4
4
  require 'simplecov'
5
5
  SimpleCov.start do
6
- minimum_coverage line: 100
6
+ minimum_coverage line: 100 unless ENV['NO_SIMPLECOV']
7
7
  add_filter '/test/'
8
8
  add_filter '/fast_arc4.rb'
9
9
  end
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.26.2
4
+ version: 0.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-21 00:00:00.000000000 Z
11
+ date: 2022-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: openssl
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 2.2.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 2.2.1
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: kramdown
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +114,48 @@ dependencies:
100
114
  - - "~>"
101
115
  - !ruby/object:Gem::Version
102
116
  version: '1.0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: webrick
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rake
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: simplecov
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
103
159
  description: |
104
160
  HexaPDF is a pure Ruby library with an accompanying application for working with PDF
105
161
  files.
@@ -234,6 +290,7 @@ files:
234
290
  - examples/020-column_box.rb
235
291
  - examples/021-list_box.rb
236
292
  - examples/022-outline.rb
293
+ - examples/023-images.rb
237
294
  - examples/emoji-smile.png
238
295
  - examples/emoji-wink.png
239
296
  - examples/machupicchu.jpg
@@ -699,14 +756,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
699
756
  requirements:
700
757
  - - ">="
701
758
  - !ruby/object:Gem::Version
702
- version: '2.5'
759
+ version: '2.6'
703
760
  required_rubygems_version: !ruby/object:Gem::Requirement
704
761
  requirements:
705
762
  - - ">="
706
763
  - !ruby/object:Gem::Version
707
764
  version: '0'
708
765
  requirements: []
709
- rubygems_version: 3.2.32
766
+ rubygems_version: 3.4.1
710
767
  signing_key:
711
768
  specification_version: 4
712
769
  summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby