hexapdf 1.3.0 → 1.4.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/lib/hexapdf/cli/form.rb +9 -4
  4. data/lib/hexapdf/configuration.rb +10 -0
  5. data/lib/hexapdf/dictionary_fields.rb +1 -1
  6. data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -2
  7. data/lib/hexapdf/document/annotations.rb +47 -0
  8. data/lib/hexapdf/document/layout.rb +73 -33
  9. data/lib/hexapdf/document/metadata.rb +10 -3
  10. data/lib/hexapdf/document.rb +9 -0
  11. data/lib/hexapdf/encryption/standard_security_handler.rb +7 -2
  12. data/lib/hexapdf/layout/box.rb +5 -0
  13. data/lib/hexapdf/layout/container_box.rb +63 -28
  14. data/lib/hexapdf/layout/style.rb +28 -13
  15. data/lib/hexapdf/layout/table_box.rb +20 -2
  16. data/lib/hexapdf/type/annotations/appearance_generator.rb +94 -16
  17. data/lib/hexapdf/type/annotations/interior_color.rb +1 -1
  18. data/lib/hexapdf/type/annotations/line.rb +1 -157
  19. data/lib/hexapdf/type/annotations/line_ending_styling.rb +208 -0
  20. data/lib/hexapdf/type/annotations/markup_annotation.rb +0 -1
  21. data/lib/hexapdf/type/annotations/polygon.rb +64 -0
  22. data/lib/hexapdf/type/annotations/polygon_polyline.rb +109 -0
  23. data/lib/hexapdf/type/annotations/polyline.rb +64 -0
  24. data/lib/hexapdf/type/annotations.rb +4 -0
  25. data/lib/hexapdf/type/measure.rb +57 -0
  26. data/lib/hexapdf/type.rb +1 -0
  27. data/lib/hexapdf/version.rb +1 -1
  28. data/test/hexapdf/digital_signature/signing/test_default_handler.rb +0 -1
  29. data/test/hexapdf/document/test_annotations.rb +20 -0
  30. data/test/hexapdf/document/test_layout.rb +16 -10
  31. data/test/hexapdf/document/test_metadata.rb +13 -1
  32. data/test/hexapdf/encryption/test_standard_security_handler.rb +2 -1
  33. data/test/hexapdf/layout/test_box.rb +8 -0
  34. data/test/hexapdf/layout/test_container_box.rb +34 -6
  35. data/test/hexapdf/layout/test_page_style.rb +1 -1
  36. data/test/hexapdf/layout/test_style.rb +20 -1
  37. data/test/hexapdf/layout/test_table_box.rb +14 -1
  38. data/test/hexapdf/test_dictionary_fields.rb +1 -0
  39. data/test/hexapdf/type/annotations/test_appearance_generator.rb +126 -0
  40. data/test/hexapdf/type/annotations/test_line.rb +0 -25
  41. data/test/hexapdf/type/annotations/test_line_ending_styling.rb +42 -0
  42. data/test/hexapdf/type/annotations/test_polygon_polyline.rb +29 -0
  43. metadata +9 -2
@@ -188,10 +188,11 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
188
188
  refute(dict.value.key?(:Perms))
189
189
  crypt_filter.call(dict, 4, :AESV2, 16)
190
190
 
191
- dict = @handler.set_up_encryption(key_length: 256, algorithm: :aes)
191
+ dict = @handler.set_up_encryption(key_length: 256, algorithm: :aes, owner_password: 'hexapdf')
192
192
  assert_equal(32, dict[:UE].length)
193
193
  assert_equal(32, dict[:OE].length)
194
194
  assert_equal(16, dict[:Perms].length)
195
+ assert(@handler.send(:owner_password_valid?, 'hexapdf'))
195
196
  crypt_filter.call(dict, 6, :AESV3, 32)
196
197
  end
197
198
 
@@ -5,6 +5,14 @@ require 'hexapdf/document'
5
5
  require 'hexapdf/layout/box'
6
6
 
7
7
  describe HexaPDF::Layout::Box::FitResult do
8
+ it "allows setting the status to failure" do
9
+ result = HexaPDF::Layout::Box::FitResult.new(nil)
10
+ result.overflow!
11
+ refute(result.failure?)
12
+ result.failure!
13
+ assert(result.failure?)
14
+ end
15
+
8
16
  it "shows the box's mask area on #draw when using debug output" do
9
17
  doc = HexaPDF::Document.new(config: {'debug' => true})
10
18
  canvas = doc.pages.add.canvas
@@ -10,6 +10,10 @@ describe HexaPDF::Layout::ContainerBox do
10
10
  @frame = HexaPDF::Layout::Frame.new(0, 0, 100, 100)
11
11
  end
12
12
 
13
+ def child_box(height: 0, width: 0, **style_properties)
14
+ @doc.layout.box(height: height, width: width, style: style_properties)
15
+ end
16
+
13
17
  def create_box(children, **kwargs)
14
18
  HexaPDF::Layout::ContainerBox.new(children: Array(children), **kwargs)
15
19
  end
@@ -48,17 +52,41 @@ describe HexaPDF::Layout::ContainerBox do
48
52
 
49
53
  describe "fit_content" do
50
54
  it "fits the children according to their mask_mode, valign, and align style properties" do
51
- box = create_box([@doc.layout.box(height: 20),
52
- @doc.layout.box(height: 20, style: {valign: :bottom, mask_mode: :fill_horizontal}),
53
- @doc.layout.box(width: 20, style: {align: :right, mask_mode: :fill_vertical})])
55
+ box = create_box([child_box(height: 20),
56
+ child_box(height: 20, valign: :bottom, mask_mode: :fill_horizontal),
57
+ child_box(width: 20, align: :right, mask_mode: :fill_vertical)])
54
58
  check_box(box, 100, 100, [[0, 80], [0, 0], [80, 20]])
55
59
  end
56
60
 
57
61
  it "respects the initially set width/height as well as border/padding" do
58
- box = create_box(@doc.layout.box(height: 20), height: 50, width: 40,
62
+ box = create_box(child_box(height: 20), height: 50, width: 40,
59
63
  style: {padding: 2, border: {width: 3}})
60
64
  check_box(box, 40, 50, [[5, 75]])
61
65
  end
66
+
67
+ it "fails if splitting is not allowed and the content is too big" do
68
+ box = create_box([child_box(height: 80), child_box(height: 30)])
69
+ box.fit(@frame.available_width, @frame.available_height, @frame)
70
+ assert(box.fit_result.failure?)
71
+ end
72
+
73
+ it "splits the box if splitting is allowed and the content is too big" do
74
+ box = create_box([child_box(height: 80), child_box(height: 30)], splitable: true)
75
+ box.fit(@frame.available_width, @frame.available_height, @frame)
76
+ assert(box.fit_result.overflow?)
77
+ end
78
+ end
79
+
80
+ describe "split_content" do
81
+ it "assigns the overflown boxes to the split box" do
82
+ box = create_box([child_box(height: 80), child_box(height: 30)], splitable: true)
83
+ box.fit(@frame.available_width, @frame.available_height, @frame)
84
+ assert(box.fit_result.overflow?)
85
+ box_a, box_b = box.split
86
+ assert_same(box, box_a)
87
+ assert(box_b.split_box?)
88
+ assert_equal(1, box_b.children.size)
89
+ end
62
90
  end
63
91
 
64
92
  describe "draw_content" do
@@ -67,10 +95,10 @@ describe HexaPDF::Layout::ContainerBox do
67
95
  end
68
96
 
69
97
  it "draws the result onto the canvas" do
70
- child_box = @doc.layout.box(height: 20) do |canvas, b|
98
+ cbox = @doc.layout.box(height: 20) do |canvas, b|
71
99
  canvas.line(0, 0, b.content_width, b.content_height).end_path
72
100
  end
73
- box = create_box(child_box)
101
+ box = create_box(cbox)
74
102
  box.fit(100, 100, @frame)
75
103
  box.draw(@canvas, 0, 50)
76
104
  assert_operators(@canvas.contents, [[:save_graphics_state],
@@ -49,7 +49,7 @@ describe HexaPDF::Layout::PageStyle do
49
49
  assert_equal("", page1.contents)
50
50
  assert_equal(523.275591, style.frame.width)
51
51
 
52
- page2 = style.create_page(@doc)
52
+ style.create_page(@doc)
53
53
  refute_same(frame1, style.frame)
54
54
  end
55
55
 
@@ -136,6 +136,19 @@ describe HexaPDF::Layout::Style::Quad do
136
136
  assert_equal(new_quad.bottom, quad.bottom)
137
137
  assert_equal(new_quad.left, quad.left)
138
138
  end
139
+
140
+ it "works with a Hash as value" do
141
+ quad = create_quad(top: 5, left: 10)
142
+ assert_equal(5, quad.top)
143
+ assert_equal(0, quad.bottom)
144
+ assert_equal(10, quad.left)
145
+ assert_equal(0, quad.right)
146
+ quad.set(right: 7)
147
+ assert_equal(5, quad.top)
148
+ assert_equal(0, quad.bottom)
149
+ assert_equal(10, quad.left)
150
+ assert_equal(7, quad.right)
151
+ end
139
152
  end
140
153
 
141
154
  it "can be asked if it contains only a single value" do
@@ -744,7 +757,7 @@ describe HexaPDF::Layout::Style do
744
757
  @style.line_spacing = 1.2
745
758
  assert_equal(0.005, @style.scaled_font_size)
746
759
  assert_equal([[:font, @style.font], [:font_size, 5], [:horizontal_scaling, 100],
747
- [:line_spacing, @style.line_spacing], [:subscript, false], [:superscript, false]],
760
+ [:line_spacing, @style.line_spacing]],
748
761
  @style.each_property.to_a.sort)
749
762
  end
750
763
  end
@@ -887,6 +900,9 @@ describe HexaPDF::Layout::Style do
887
900
  end
888
901
 
889
902
  it "handles subscript" do
903
+ @style.subscript = false
904
+ assert_equal(10, @style.calculated_font_size)
905
+ assert_equal(0, @style.calculated_text_rise)
890
906
  @style.subscript = true
891
907
  assert_in_delta(5.83, @style.calculated_font_size)
892
908
  assert_in_delta(0.00583, @style.scaled_font_size, 0.000001)
@@ -894,6 +910,9 @@ describe HexaPDF::Layout::Style do
894
910
  end
895
911
 
896
912
  it "handles superscript" do
913
+ @style.superscript = false
914
+ assert_equal(10, @style.calculated_font_size)
915
+ assert_equal(0, @style.calculated_text_rise)
897
916
  @style.superscript = true
898
917
  assert_in_delta(5.83, @style.calculated_font_size)
899
918
  assert_in_delta(3.30, @style.calculated_text_rise)
@@ -116,6 +116,18 @@ describe HexaPDF::Layout::TableBox::Cell do
116
116
  assert_equal(12, cell.preferred_height)
117
117
  end
118
118
 
119
+ it "respects the set minimum height of the cell" do
120
+ cell = create_cell(children: HexaPDF::Layout::Box.create(width: 20, height: 10), min_height: 30)
121
+ assert(cell.fit(100, 25, @frame).failure?)
122
+
123
+ assert(cell.fit(100, 100, @frame).success?)
124
+ assert_equal(30, cell.height)
125
+
126
+ cell = create_cell(children: HexaPDF::Layout::Box.create(width: 20, height: 20), min_height: 2)
127
+ assert(cell.fit(100, 100, @frame).success?)
128
+ assert_equal(32, cell.height)
129
+ end
130
+
119
131
  it "doesn't fit children that are too big" do
120
132
  cell = create_cell(children: HexaPDF::Layout::Box.create(width: 300, height: 20))
121
133
  assert(cell.fit(100, 100, @frame).failure?)
@@ -262,7 +274,7 @@ describe HexaPDF::Layout::TableBox::Cells do
262
274
  end
263
275
 
264
276
  it "sets the correct information on the created cells" do
265
- cells = create_cells([[:a, {col_span: 2, content: :b}],
277
+ cells = create_cells([[:a, {col_span: 2, content: :b, min_height: 30}],
266
278
  [{col_span: 2, row_span: 2, content: :c}, {row_span: 2, content: :d}]])
267
279
  assert_equal(0, cells[0, 0].row)
268
280
  assert_equal(0, cells[0, 0].column)
@@ -272,6 +284,7 @@ describe HexaPDF::Layout::TableBox::Cells do
272
284
  assert_equal(1, cells[0, 1].column)
273
285
  assert_equal(1, cells[0, 1].row_span)
274
286
  assert_equal(2, cells[0, 1].col_span)
287
+ assert_equal(30, cells[0, 1].instance_variable_get(:@min_height))
275
288
  assert_equal(1, cells[1, 0].row)
276
289
  assert_equal(0, cells[1, 0].column)
277
290
  assert_equal(2, cells[1, 0].row_span)
@@ -193,6 +193,7 @@ describe HexaPDF::DictionaryFields do
193
193
  ["D:19981223195210Z00'00", [1998, 12, 23, 19, 52, 10, "+00:00"]],
194
194
  ["D:19981223195210-08", [1998, 12, 23, 19, 52, 10, "-08:00"]], # missing '
195
195
  ["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], # no trailing ', as per PDF 2.0
196
+ ["D:19981223195210-08'00''", [1998, 12, 23, 19, 52, 10, "-08:00"]], # two trailing '
196
197
  ["D:19981223195210-54'00", [1998, 12, 23, 19, 52, 10, "-23:59:59"]], # TZ hour too large
197
198
  ["D:19981223195210+10'65", [1998, 12, 23, 19, 52, 10, "+11:05"]], # TZ min too large
198
199
  ["D:19982423195210-08'00'", [1998, 12, 23, 19, 52, 10, "-08:00"]], # months too large
@@ -479,4 +479,130 @@ describe HexaPDF::Type::Annotations::AppearanceGenerator do
479
479
  [:stroke_path]])
480
480
  end
481
481
  end
482
+
483
+ describe "polygon/polyline" do
484
+ before do
485
+ @polyline = @doc.add({Type: :Annot, Subtype: :PolyLine, C: [0],
486
+ Vertices: [100, 100, 200, 150, 210, 80]})
487
+ @generator = HexaPDF::Type::Annotations::AppearanceGenerator.new(@polyline)
488
+ end
489
+
490
+ it "sets the print flag and unsets the hidden flag" do
491
+ @polyline.flag(:hidden)
492
+ @generator.create_appearance
493
+ assert(@polyline.flagged?(:print))
494
+ refute(@polyline.flagged?(:hidden))
495
+ end
496
+
497
+ it "creates a simple polyline" do
498
+ @generator.create_appearance
499
+ assert_equal([96, 76, 214, 154], @polyline[:Rect])
500
+ assert_equal([96, 76, 214, 154], @polyline.appearance[:BBox])
501
+ assert_operators(@polyline.appearance.stream,
502
+ [[:move_to, [100, 100]],
503
+ [:line_to, [200, 150]],
504
+ [:line_to, [210, 80]],
505
+ [:stroke_path]])
506
+ end
507
+
508
+ it "creates a simple polygon" do
509
+ @polyline[:Subtype] = :Polygon
510
+ @generator.create_appearance
511
+ assert_operators(@polyline.appearance.stream,
512
+ [[:move_to, [100, 100]],
513
+ [:line_to, [200, 150]],
514
+ [:line_to, [210, 80]],
515
+ [:close_subpath],
516
+ [:stroke_path]])
517
+ end
518
+
519
+ describe "stroke color" do
520
+ it "uses the specified border color for stroking operations" do
521
+ @polyline.border_style(color: "red")
522
+ @generator.create_appearance
523
+ assert_operators(@polyline.appearance.stream,
524
+ [:set_device_rgb_stroking_color, [1, 0, 0]], range: 0)
525
+ assert_operators(@polyline.appearance.stream,
526
+ [:stroke_path], range: 4)
527
+ end
528
+
529
+ it "works with a transparent border" do
530
+ @polyline.border_style(color: :transparent)
531
+ @generator.create_appearance
532
+ assert_operators(@polyline.appearance.stream, [:end_path], range: 3)
533
+ end
534
+ end
535
+
536
+ describe "interior color" do
537
+ it "uses the specified interior color for non-stroking operations" do
538
+ @polyline[:Subtype] = :Polygon
539
+ @polyline.border_style(color: :transparent)
540
+ @polyline.interior_color("red")
541
+ @generator.create_appearance
542
+ assert_operators(@polyline.appearance.stream,
543
+ [:set_device_rgb_non_stroking_color, [1, 0, 0]], range: 0)
544
+ assert_operators(@polyline.appearance.stream,
545
+ [:fill_path_non_zero], range: 5)
546
+ end
547
+
548
+ it "works together with the stroke color" do
549
+ @polyline[:Subtype] = :Polygon
550
+ @polyline.interior_color("red")
551
+ @generator.create_appearance
552
+ assert_operators(@polyline.appearance.stream,
553
+ [:set_device_rgb_non_stroking_color, [1, 0, 0]], range: 0)
554
+ assert_operators(@polyline.appearance.stream,
555
+ [:fill_and_stroke_path_non_zero], range: 5)
556
+ end
557
+
558
+ it "works if neither interior nor border color is used" do
559
+ @polyline[:Subtype] = :Polygon
560
+ @polyline.interior_color(:transparent)
561
+ @polyline.border_style(color: :transparent)
562
+ @generator.create_appearance
563
+ assert_operators(@polyline.appearance.stream,
564
+ [:end_path], range: 4)
565
+ end
566
+ end
567
+
568
+ it "sets the specified border line width" do
569
+ @polyline.border_style(width: 4)
570
+ @generator.create_appearance
571
+ assert_operators(@polyline.appearance.stream,
572
+ [:set_line_width, [4]], range: 0)
573
+ end
574
+
575
+ it "sets the specified line dash pattern if it is an array" do
576
+ @polyline.border_style(style: [5, 2])
577
+ @generator.create_appearance
578
+ assert_operators(@polyline.appearance.stream,
579
+ [:set_line_dash_pattern, [[5, 2], 0]], range: 0)
580
+ end
581
+
582
+ it "sets the specified opacity" do
583
+ @polyline.opacity(fill_alpha: 0.5, stroke_alpha: 0.5)
584
+ @generator.create_appearance
585
+ assert_operators(@polyline.appearance.stream,
586
+ [:set_graphics_state_parameters, [:GS1]], range: 0)
587
+ end
588
+
589
+ it "draws the specified line ending style" do
590
+ @polyline.line_ending_style(start_style: :open_arrow, end_style: :rclosed_arrow)
591
+ @polyline.border_style(width: 2)
592
+ @polyline.interior_color("red")
593
+ @generator.create_appearance
594
+ assert_equal([86, 52, 238, 158], @polyline[:Rect])
595
+ assert_equal([86, 52, 238, 158], @polyline.appearance[:BBox])
596
+ assert_operators(@polyline.appearance.stream,
597
+ [[:move_to, [109.917818, 115.021215]],
598
+ [:line_to, [100, 100]],
599
+ [:line_to, [117.967662, 98.921525]],
600
+ [:stroke_path],
601
+ [:move_to, [221.114086, 94.158993]],
602
+ [:line_to, [210, 80]],
603
+ [:line_to, [203.294995, 96.704578]],
604
+ [:close_subpath],
605
+ [:fill_and_stroke_path_non_zero]], range: 6..-1)
606
+ end
607
+ end
482
608
  end
@@ -26,31 +26,6 @@ describe HexaPDF::Type::Annotations::Line do
26
26
  end
27
27
  end
28
28
 
29
- describe "line_ending_style" do
30
- it "returns the current style" do
31
- assert_kind_of(HexaPDF::Type::Annotations::Line::LineEndingStyle, @line.line_ending_style)
32
- assert_equal([:none, :none], @line.line_ending_style.to_a)
33
- @line[:LE] = [:Diamond, :OpenArrow]
34
- assert_equal([:diamond, :open_arrow], @line.line_ending_style.to_a)
35
- @line[:LE] = [:Diamond, :Unknown]
36
- assert_equal([:diamond, :none], @line.line_ending_style.to_a)
37
- end
38
-
39
- it "sets the style" do
40
- assert_same(@line, @line.line_ending_style(start_style: :OpenArrow))
41
- assert_equal([:OpenArrow, :None], @line[:LE])
42
- assert_same(@line, @line.line_ending_style(end_style: :open_arrow))
43
- assert_equal([:OpenArrow, :OpenArrow], @line[:LE])
44
- assert_same(@line, @line.line_ending_style(start_style: :circle, end_style: :ClosedArrow))
45
- assert_equal([:Circle, :ClosedArrow], @line[:LE])
46
- end
47
-
48
- it "raises an error for unknown styles" do
49
- assert_raises(ArgumentError) { @line.line_ending_style(start_style: :unknown) }
50
- assert_raises(ArgumentError) { @line.line_ending_style(end_style: :unknown) }
51
- end
52
- end
53
-
54
29
  describe "leader_line_length" do
55
30
  it "returns the leader line length" do
56
31
  assert_equal(0, @line.leader_line_length)
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/annotations/line_ending_styling'
6
+
7
+ describe HexaPDF::Type::Annotations::LineEndingStyling do
8
+ class TestAnnotLineEndingStyling < HexaPDF::Type::Annotation
9
+ define_field :LE, type: HexaPDF::PDFArray, default: [:None, :None]
10
+ include HexaPDF::Type::Annotations::LineEndingStyling
11
+ end
12
+
13
+ before do
14
+ @doc = HexaPDF::Document.new
15
+ @annot = @doc.wrap({Type: :Annot}, type: TestAnnotLineEndingStyling)
16
+ end
17
+
18
+ describe "line_ending_style" do
19
+ it "returns the current style" do
20
+ assert_kind_of(HexaPDF::Type::Annotations::Line::LineEndingStyle, @annot.line_ending_style)
21
+ assert_equal([:none, :none], @annot.line_ending_style.to_a)
22
+ @annot[:LE] = [:Diamond, :OpenArrow]
23
+ assert_equal([:diamond, :open_arrow], @annot.line_ending_style.to_a)
24
+ @annot[:LE] = [:Diamond, :Unknown]
25
+ assert_equal([:diamond, :none], @annot.line_ending_style.to_a)
26
+ end
27
+
28
+ it "sets the style" do
29
+ assert_same(@annot, @annot.line_ending_style(start_style: :OpenArrow))
30
+ assert_equal([:OpenArrow, :None], @annot[:LE])
31
+ assert_same(@annot, @annot.line_ending_style(end_style: :open_arrow))
32
+ assert_equal([:OpenArrow, :OpenArrow], @annot[:LE])
33
+ assert_same(@annot, @annot.line_ending_style(start_style: :circle, end_style: :ClosedArrow))
34
+ assert_equal([:Circle, :ClosedArrow], @annot[:LE])
35
+ end
36
+
37
+ it "raises an error for unknown styles" do
38
+ assert_raises(ArgumentError) { @annot.line_ending_style(start_style: :unknown) }
39
+ assert_raises(ArgumentError) { @annot.line_ending_style(end_style: :unknown) }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/annotations/polygon_polyline'
6
+
7
+ describe HexaPDF::Type::Annotations::PolygonPolyline do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @annot = @doc.add({Type: :Annot, Subtype: :Polyline, Rect: [0, 0, 0, 0]},
11
+ type: HexaPDF::Type::Annotations::PolygonPolyline)
12
+ end
13
+
14
+ describe "vertices" do
15
+ it "returns the coordinates of the vertices" do
16
+ @annot[:Vertices] = [10, 20, 30, 40, 50, 60]
17
+ assert_equal([10, 20, 30, 40, 50, 60], @annot.vertices)
18
+ end
19
+
20
+ it "sets the vertices" do
21
+ assert_same(@annot, @annot.vertices(1, 2, 3, 4, 5, 6))
22
+ assert_equal([1, 2, 3, 4, 5, 6], @annot[:Vertices])
23
+ end
24
+
25
+ it "raises an ArgumentError if an uneven number of arguments is provided" do
26
+ assert_raises(ArgumentError) { @annot.vertices(1, 2, 3) }
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-23 00:00:00.000000000 Z
10
+ date: 2025-08-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: cmdparse
@@ -514,8 +514,12 @@ files:
514
514
  - lib/hexapdf/type/annotations/circle.rb
515
515
  - lib/hexapdf/type/annotations/interior_color.rb
516
516
  - lib/hexapdf/type/annotations/line.rb
517
+ - lib/hexapdf/type/annotations/line_ending_styling.rb
517
518
  - lib/hexapdf/type/annotations/link.rb
518
519
  - lib/hexapdf/type/annotations/markup_annotation.rb
520
+ - lib/hexapdf/type/annotations/polygon.rb
521
+ - lib/hexapdf/type/annotations/polygon_polyline.rb
522
+ - lib/hexapdf/type/annotations/polyline.rb
519
523
  - lib/hexapdf/type/annotations/square.rb
520
524
  - lib/hexapdf/type/annotations/square_circle.rb
521
525
  - lib/hexapdf/type/annotations/text.rb
@@ -539,6 +543,7 @@ files:
539
543
  - lib/hexapdf/type/info.rb
540
544
  - lib/hexapdf/type/mark_information.rb
541
545
  - lib/hexapdf/type/marked_content_reference.rb
546
+ - lib/hexapdf/type/measure.rb
542
547
  - lib/hexapdf/type/metadata.rb
543
548
  - lib/hexapdf/type/names.rb
544
549
  - lib/hexapdf/type/namespace.rb
@@ -800,7 +805,9 @@ files:
800
805
  - test/hexapdf/type/annotations/test_border_styling.rb
801
806
  - test/hexapdf/type/annotations/test_interior_color.rb
802
807
  - test/hexapdf/type/annotations/test_line.rb
808
+ - test/hexapdf/type/annotations/test_line_ending_styling.rb
803
809
  - test/hexapdf/type/annotations/test_markup_annotation.rb
810
+ - test/hexapdf/type/annotations/test_polygon_polyline.rb
804
811
  - test/hexapdf/type/annotations/test_text.rb
805
812
  - test/hexapdf/type/annotations/test_widget.rb
806
813
  - test/hexapdf/type/test_annotation.rb